Thêm một Friend vào FriendList: Mô hình xử lý:
Thêm Friend vào FriendList
Hiển thị màn hình thêm Friend Yêu cầu thêm Friend
Thêm Friend vào FriendList
Chưa tồn tại Kiểm tra Friend tồn tại trong FriendList
Kiểm tra tồn tại Gởi tên Friend
Yêu cầu thêm Friend
Thông báo thêm Friend thành công
Thêm Friend thành công
Friend tồn tại
Kiểm tra tồn tại Kiểm tra tồn tại
Nhập tên Friend
Yêu cầu nhập tên Friend cần thêm Người dùng
Màn hình chính Màn hình thêm Friend Server Table Users Table FriendList
Hiển thị màn hình thêm Friend Yêu cầu thêm Friend
Thêm Friend vào FriendList
Chưa tồn tại Kiểm tra Friend tồn tại trong FriendList
Kiểm tra tồn tại Gởi tên Friend
Yêu cầu thêm Friend
Thông báo thêm Friend thành công
Thêm Friend thành công
Friend tồn tại
Kiểm tra tồn tại Kiểm tra tồn tại
Nhập tên Friend
Yêu cầu nhập tên Friend cần thêm
Hình 3-8: Mô hình xử lý thêm Friend
Mô tả qui trình xử lý:
Khi người dùng chọn chức năng thêm một Friend vào FriendList, màn hình thêm FriendList sẽ được mở ra. Người dùng sẽ nhập tên của Friend và sau đó Client sẽ gởi tên Friend này lên cho Server. Trước tiên, Server sẽ kiểm tra Friend này có tồn tại hay không. Tiếp theo, sẽ kiểm tra Friend này đã được thêm vào FriendList trước đó hay chưa. Nếu Friend này chưa có trong FriendList, Server sẽ thêm Friend này vào FriendList của người dùng. Cuối cùng, Server sẽ gởi kết quả của công việc về cho Client. Dựa vào kết quả nhận được, Client sẽ thông báo cho người dùng biết là việc thêm thành
công hay thất bại (có hai nguyên nhân thất bại là Friend không tồn tại và Friend đã có trong FriendList rồi).
Xóa một Friend ra khỏi FriendList: Mô hình xử lý:
Xóa Friend ra khỏi FriendList
Thông báo xóa thành công
Xóa thành công
Xóa Friend ra khỏi FriendList Friend tồn tại trong FriendList
Kiểm tra tồn tại Kiểm tra Friend tồn tại trong FriendList
Kiểm tra tồn tại
Friend tồn tại Tên Friend
Kiểm tra tồn tại Yêu cầu xóa Friend ra khỏi FriendList
Nhập tên Friend
Yêu cầu nhập tên Friend cần xóa
Hiển thị màn hình xóa Friend Yêu cầu xóa Friend
Người dùng
Màn hình chính Màn hình xóa Friend Server Table Users Table FriendList
Thông báo xóa thành công
Xóa thành công
Xóa Friend ra khỏi FriendList Friend tồn tại trong FriendList
Kiểm tra tồn tại Kiểm tra Friend tồn tại trong FriendList
Kiểm tra tồn tại
Friend tồn tại Tên Friend
Kiểm tra tồn tại Yêu cầu xóa Friend ra khỏi FriendList
Nhập tên Friend
Yêu cầu nhập tên Friend cần xóa
Hiển thị màn hình xóa Friend Yêu cầu xóa Friend
Hình 3-9: Mô hình xử lý xóa Friend
Mô tả qui trình xử lý:
Khi người dùng chọn chức năng xóa một Friend vào FriendList, màn hình thêm FriendList sẽ được mở ra. Người dùng sẽ nhập tên của Friend và sau đó Client sẽ gởi tên Friend này lên cho Server. Trước tiên, Server sẽ kiểm tra Friend này có tồn tại hay không. Tiếp theo, sẽ kiểm tra Friend này đã được thêm vào FriendList trước đó hay chưa. Nếu Friend này đã có trong FriendList, Server sẽ xóa Friend này ra khỏi FriendList của người dùng. Cuối cùng, Server sẽ gởi kết quả của công việc về cho Client. Dựa vào kết quả nhận
được, Client sẽ thông báo cho người dùng biết là việc Xóa thành công hay thất bại (có hai nguyên nhân thất bại là Friend không tồn tại và Friend chưa có trong FriendList) đồng thời cập nhật lại màn hình chính nếu cần.
Ghi chú: Chức năng này có thể được gọi khi người dùng nhấn phím Delete trong Listbox FriendList.
4.1.4.4 Mô hình luồng xử lý Group Chat
Khi User tạo Group: Mô hình xử lý:
T ạo Group
Tập hợp các User tồn tại
Kiểm tra tồn tại Mở Tab Group Chat
Gởi tên các Users và tên Group Yêu cầu tạo Group
Nhập tên các User cần mời vào Group
Yêu cầu chọn các User được mời vào Group
Hiển thị màn hình tạo Group Yêu cầu tạo Group
Người tạo group
Màn hình chính Màn hình tạo group Table Users
Người được mời Server
Tập hợp các User tồn tại
Kiểm tra tồn tại Mở Tab Group Chat
Gởi tên các Users và tên Group Yêu cầu tạo Group
Nhập tên các User cần mời vào Group
Yêu cầu chọn các User được mời vào Group
Hiển thị màn hình tạo Group Yêu cầu tạo Group
Hình 3-10:Mô hình xử lý tạo Group
Mô tả qui trình xử lý:
Khi người dùng chọn chức năng Invite Group thì màn hình tạo Group sẽ xuất hiện. Người dùng nhập danh sách các Users muốn mời và có thể nhập thêm Invite Message rồi nhấn Invite. Client sẽ tự phát
sinh ra tên Group và sẽ gởi kèm nó với danh sách các Users muốn mời đồng thời cũng mở thêm một Tab Group Chat. Server sẽ lọc ra các Users đang Online trong danh sách các Users được mời. Sau đó, Server sẽ gởi lời mời kèm theo tên người mời đến các Users được mời.
Khi User đồng ý gia nhập Group: Mô hình xử lý:
Đồng ý gia nhập Group
Thêm người dủng này vào Group Chat
Cập nhật Tab Group Chat
Đồng ý tham gia Group
Tập hợp các User tham gia Group
Thêm Group Kiểm tra Group
Tập hợp các User đã tham gia Group
Các User đã tham gia Group Group chưa tồn tại
Mở Tab GroupChat Đồng ý gia nhập Group
Màn hình chính Server Table GroupChat T able GroupDetail
Người dùng User đã tham gia Group
Thêm người dủng này vào Group Chat
Cập nhật Tab Group Chat
Đồng ý tham gia Group
Tập hợp các User tham gia Group
Thêm Group Kiểm tra Group
Tập hợp các User đã tham gia Group
Các User đã tham gia Group Group chưa tồn tại
Mở Tab GroupChat Đồng ý gia nhập Group
Hình 3-11: Mô hình xử lý đồng ý gia nhập Group
Mô tả qui trình xử lý:
Khi người dùng đồng ý lời mời gia nhập nhóm, Client sẽ gởi thông báo đồng ý cho Server. Server sẽ kiểm tra xem Group này đã được lưu hay chưa (Group chưa được lưu nếu chưa có người dùng nào đồng ý tham gia). Sau đó, Server sẽ lưu người dùng này vào GroupDetail. Cuối cùng, Server sẽ gởi tên tất cả các Users đã tham gia Group cho người dùng, đồng thời cũng gởi thông báo đến cho các Users trong Group là người dùng này đã đồng ý gia nhập nhóm.
Khi User thoát khỏi Group: Mô hình xử lý:
Rời khỏi Group
Gởi thông báo thoát khỏi Group kèm theo tên Group
Lấy danh sách các Users có trong Group
Thông báo đến các Users trong Group Danh sách các User có trong Group
Cập nhật lại màn hình chính Đóng Tab Group Chat
Người dùng
Màn hình chính Server Table GroupDetail
Users
Gởi thông báo thoát khỏi Group kèm theo tên Group
Lấy danh sách các Users có trong Group
Thông báo đến các Users trong Group Danh sách các User có trong Group
Cập nhật lại màn hình chính Đóng Tab Group Chat
Hình 3-12: Mô hình xử lý thoát khỏi Group
Mô tả qui trình xử lý:
Khi một người dùng tắt Tab Group Chat, Client sẽ gởi thông báo thoát khỏi Group cho Server. Server trước tiên kiểm tra người dùng này có phải là người đã tạo Group hay không. Nếu không phải, Server sẽ gởi thông báo tới các Users khác trong Group. Cuối cùng, Server sẽ cập nhật lại GroupDetail.
Khi User hủy Group: Mô hình xử lý: Hủy Group
Gởi thông báo thoát khỏi Group
Xóa GroupDetail
Thông báo hủy Group Danh sách các Users có trong Group
Lấy danh sách các Users có trong Group Kiểm tra đúng
Kiểm tra người tạo group Kiểm tra người dùng có tạo ra group này hay không
Đóng Tab Group Chat
Cập nhật màn hình chính Người dùng
Màn hình chính Server Table GroupChat Table GroupDetail
Users
Gởi thông báo thoát khỏi Group
Xóa GroupDetail
Thông báo hủy Group Danh sách các Users có trong Group
Lấy danh sách các Users có trong Group Kiểm tra đúng
Kiểm tra người tạo group Kiểm tra người dùng có tạo ra group này hay không
Đóng Tab Group Chat
Cập nhật màn hình chính
Hình 3-13: Mô hình xử lý hủy Group
Mô tả:
Khi một người dùng tắt Tab Group Chat, Client sẽ gởi thông báo thoát khỏi Group cho Server. Server trước tiên kiểm tra người dùng này có phải là người đã tạo Group hay không. Nếu đúng, Server sẽ gởi thông báo hủy Group tới các Users khác trong Group. Cuối cùng, Server sẽ xóa Group này khỏi GroupDetail và GroupChat.
Ghi chú: Khi nhận được thông báo hủy Group từ Users, Client sẽ tắt Tab Group Chat tương ứng đồng thời thông báo cho người dùng.
Khi User gởi tin nhắn tới các thành viên trong Group: Mô hình xử lý:
Gởi tin nhắn trong Group
Danh sách các Users trong Group Lấy danh sách các Users trong Group
Hiển thị tin nhắn
Gởi tin nhắn kèm theo tên Group Chọn Tab Group Chat và yêu cầu chức năng gời tin nhắn
Nhập tin nhắn Ngưởi gởi
Màn hình chính Server T able GroupDetail
Các Users trong Group
Danh sách các Users trong Group Lấy danh sách các Users trong Group
Hiển thị tin nhắn
Gởi tin nhắn kèm theo tên Group Chọn Tab Group Chat và yêu cầu chức năng gời tin nhắn
Nhập tin nhắn
Hình 3-14: Mô hình xử lý gởi tin nhắn trong Group
Mô tả qui trình xử lý:
Khi người dùng nhập tin nhắn và nhấn button Send trong Tab Group Chat, Client sẽ gởi tin nhắn và tên Group cho Server. Dựa vào tên Group nhận được, Server sẽ tìm tất cả các Users đã tham gia Group và gởi tin nhắn kèm theo tên người gởi đến các Users này.
4.2 Thiết kế các lớp xữ lý
4.2.1 Lớp DataLayer:
Mô hình:
Hình 3-15: Mô hình lớp DataLayer
Chức năng: Xử lý các câu lệnh về cơ sở dữ liệu tông quát, kiểm tra và thay đổi kết nối đến cơ sở dữ liệu.
4.2.2 Lớp MyDatabase:
Mô hình:
Chức năng: Thực hiện các câu lệnh Sql cần thiết và thực thi các Store Procedure có sẳn trong cơ sở dữ liệu.
4.2.3 Lớp ImageListBoxItem
Mô hình:
Hình 3-17: Mô hình lớp ImageListBoxItem
4.2.4 Lớp ImageListBox:
Mô hình:
Hình 3-18: Mô hình lớp ImageListBox
Chức năng: Tạo ra một loại ListBox mới với Item có thể chứa được text và hình ảnh.
4.2.5 Lớp Settings:
Mô hình:
Hình 3-19: Mô hình lớp Settings
Chức năng: Chỉnh sửa và sao lưu thông tin đăng nhập vào cơ sở dữ liệu.
4.2.6 Lớp MultilineListBoxItem:
Mô hình:
Hình 3-20: Mô hình lớp MultilineListBoxItem
Chức năng: Thao tác với Item của một MultilineListBox
4.2.7 Lớp MultilineListBox:
Mô hình:
Hình 3-1: Mô hình lớp MultilineListBox
Chức năng: Kế thừa lớp ListBox để tạo ra một loại ListBox mới có thể thêm một Item lưu dữ liệu trên nhiều dòng.
4.2.8 Lớp TabControlEx:
Mô hình:
Hình 3-21: Mô hình lớp TabControlEx
Chức năng: Kế thừa từ một TabControl để tạo ra một loại TabControl mới có thể đóng, mở trực tiếp.
4.2.9 LớpMyDataPack:
Mô hình:
Hình 3-22: Mô hình lớp MyDataPack
Chức năng: Lớp MyDataPack có 2 nhiệm vụ. Nhiệm vụ thứ nhất là chuyển một mảng lưu các chức năng, chuỗi tên, tên nhóm, tin nhắn thành một dãy byte để truyền đi. Nhiệm vụ thứ hai là chuyển chuổi byte nhận được thành mảng lưu các chức năng, chuỗi tên, tên nhóm và tin nhắn để đưa cho chương trình xữ lý.
4.2.10 Lớp ClientHandler:
Mô hình:
Hình 3-23: Mô hình ClientHandler
4.3 Một số qui tắc và hàm xử lý cơ bản
4.3.1 Qui tắc gởi dữ liệu trong mạng:
Gói dữ liệu được gởi qua lại trong mạng là một khối bytes có độ dài lớn nhất là 2048 bytes. Khối bytes này có cấu trúc như sau:
2 bytes đầu tiên: Đánh dấu các chức năng của chương trình. 2 bytes tiếp theo: Đánh dấu các chức năng con thuộc chức năng chính.
2 bytes tiếp theo: Lưu các giá trị được gởi kèm theo nếu có. 4 bytes kế tiếp: Đánh dấu độ lớn của khối bytes lưu tên người nhận.
4 bytes tiếp theo: Đánh dấu độ lớn của khối bytes lưu tin nhắn. 4 bytes tiếp theo: Đánh dấu độ lớn của khối bytes lưu tên nhóm.
Các bytes còn lại: Lần lượt lưu khối bytes chứa tên, tin nhắn và tên nhóm.
Ghi chú: Các chuổi tên, tin nhắn và tên nhóm sẽ được mã hóa UTF8 trước khi được đóng gói vào khối bytes.
4.3.2 Một số hàm xữ lý cơ bản:
4.3.2.1 Hàm PackData
Mã nguồn:
Bảng 3-9: Mã nguồn hàm PackData
public byte[] PackData(int[] arr, String _name, String _mess, String _groupName) {
byte[] nameByte = Encoding.UTF8.GetBytes(_name); byte[] messByte = Encoding.UTF8.GetBytes(_mess);
byte[] groupByte = Encoding.UTF8.GetBytes(_groupName);
int len = arr.Length * 2 + 12 + nameByte.Length + messByte.Length + groupByte.Length;
byte[] data = new byte[len]; int offset = 0;
for (int i = 0; i < arr.Length; i++) {
Buffer.BlockCopy(BitConverter.GetBytes(arr[i]), 0, data, offset, 2); offset += 2; } offset = 6; Buffer.BlockCopy(BitConverter.GetBytes(nameByte.Length), 0, data, offset, 4); offset += 4; Buffer.BlockCopy(BitConverter.GetBytes(messByte.Length), 0, data, offset, 4); offset += 4; Buffer.BlockCopy(BitConverter.GetBytes(groupByte.Length), 0, data, offset, 4); offset += 4;
Buffer.BlockCopy(nameByte, 0, data, offset, nameByte.Length); offset += nameByte.Length;
Buffer.BlockCopy(messByte, 0, data, offset, messByte.Length); offset += messByte.Length;
Buffer.BlockCopy(groupByte, 0, data, offset, groupByte.Length); return data;
}
Input: Mảng lưu chứa giá trị các chức năng, tên người nhận, tin nhắn, tên nhóm.
Output: Khối bytes được đã được đóng gói. Chức năng: Đóng gói khối bytes trước khi gởi đi.
4.3.2.2 Hàm UnPackData
Mã nguồn:
Bảng 3-10: Mã nguồn hàm UnPackData
public void UnPackData(byte[] data) {
int offset = 0; for (int i = 0; i < 3; i++ ) {
byte[] tbytes = new byte[4];
Buffer.BlockCopy(data, offset, tbytes, 0, 2); array[i] = BitConverter.ToInt32(tbytes, 0);
offset += 2; }
int len;
byte[] bytes = new byte[4];
Buffer.BlockCopy(data, 6, bytes, 0, 4); len = BitConverter.ToInt32(bytes, 0); offset = 18;
if (len != 0) {
byte[] nameByte = new byte[len];
Buffer.BlockCopy(data, offset, nameByte, 0, len); name = Encoding.UTF8.GetString(nameByte, 0, len); } offset += len; Buffer.BlockCopy(data, 10, bytes, 0, 4); len = BitConverter.ToInt32(bytes, 0); if (len != 0) {
byte[] messByte = new byte[len];
Buffer.BlockCopy(data, offset, messByte, 0, len);
message = Encoding.UTF8.GetString(messByte, 0, len); }
offset += len;
Buffer.BlockCopy(data, 14, bytes, 0, 4); len = BitConverter.ToInt32(bytes, 0); if (len != 0) {
byte[] groupByte = new byte[len];
Buffer.BlockCopy(data, offset, groupByte, 0, len);
groupName = Encoding.UTF8.GetString(groupByte, 0, len); }
}
Input: Khối bytes đã được đánh dấu.
Chức năng: Giải đóng gói khối bytes nhận được. Kết quả nhận được là mảng chứa các chức năng, chuổi tên người nhận, tin nhắn và tên nhóm được lưu trong lớp DataPack.
4.3.2.3 Hàm SaveSettings và LoadSettings
Mã nguồn:
Bảng 3-11: Mã nguồn hàm SaveSettings và LoadSettings
public void SaveSettings() {
FileStream fs = File.Open("Settings.ini", FileMode.OpenOrCreate, FileAccess.Write);
BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(fs, this);
fs.Close(); }
public void LoadSettings() {
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = File.Open("Settings.ini", FileMode.Open, FileAccess.Read); Settings sett = (Settings)bf.Deserialize(fs);
servername = sett.ServerName; authencation = sett.Authencation; username = sett.Username; password = sett.Password; databasename = sett.DatabaseName; fs.Close(); }
Chức năng: Hai hàm này có chức năng lưu và lấy thông tin trong tập tin Settings.ini để thiếp lập kết nối đến cơ sở dữ liệu.
4.3.2.4 Hàm theadListen
Mã nguồn:
Bảng 3-12: Mã nguồn hàm theadListen
private void threadListen() {
myTcpListener = new TcpListener(IPAddress.Any,Convert.ToInt16(port)); myTcpListener.Start(); while (true) { try { myClient = myTcpListener.AcceptTcpClient(); allClient.Add(myClient);
ClientHandler clientHandler = new ClientHandler(myClient, port, this); thdHandler = new Thread(new
ThreadStart(clientHandler.ReceiveData)); thdHandler.Start(); } catch { myTcpListener.Stop(); } } }
Chức năng: Giúp Server tiếp nhận các kết nối từ Client, với mỗi Client tiếp nhận được thì mỡ một đối tượng ClientHandler để quản lý và tạo một Thread để thao tác.
4.4 Thiết kế dữ liệu
4.4.1 Chuẩn hóa dữ liệu:
Users (ID, Username, Password, State, Fullname, Email, Address) FriendList(UserID, FriendID)
OfflineMessage(UserID, SenderID, SendTime, Message) GroupChat(GroupID, UserID, GroupName, CreateTime) GroupDetail(FriendID, GroupID) 4.4.2 Mô hình dữ liệu ở mức vật lý: FK_GROUPCHA_RELATIONS_USERS FK_GROUPDET_GROUPDETA_USERS FK_GROUPDET_GROUPDETA_GROUPCHA FK_FRIENDLI_FRIENDLIS_USERS FK_FRIENDLI_FRIENDLIS_USERS FK_OFFLINEM_OFFLINEME_USERS FK_OFFLINEM_OFFLINEME_USERS GroupDetail FriendID GroupID int int <pk,fk1> <pk,fk2> Users ID Username Password State Fullname Email Address int varchar(20) varchar(15) bit nvarchar(50) varchar(50) nvarchar(50) <pk> GroupChat GroupID UserID GroupName int int varchar(30) <pk> <fk> FriendList UserID FriendID int int <pk,fk1> <pk,fk2> OfflineMessage UserID SenderID SendTime Message int int datetime nvarchar(500) <pk,fk1> <pk,fk2> Hình 3-24: Mô hình dữ liệu ở mức vật lý 4.4.3 Thiết kế dữ liệu:
Gồm có các bảng Users, FriendList, OfflineMessage, GroupChat, GroupDetail để lưu trử các thông tin về user để đăng nhập, quan hệ giữa các user, lưu tin nhắn offline của các user và lưu tạm thời thông tin các nhóm Chat.
Table Users
Chức năng: Lưu thông tin về User Danh sách các thuộc tính:
Bảng 3-13: Table Users
STT Tên thuộc tính Kiểu dữ liệu Diễn giải
1 ID int (4) Tự động tăng, Khóa chính
2 Username varchar (20) Tên đăng nhập 3 Password varchar (15) Mật khẩu đăng nhập 4 State bit (1) Trạng thái của User 5 Fullname nvarchar (50) Tên đầy đủ của User 6 Email varchar (30) Email của User 7 Address nvarchar (50) Địa chỉ của User
Table FriendList
Chức năng: Lưu thông tin về quan hệ giữa các User Danh sách các thuộc tính:
Bảng 3-14: Table FriendList
STT Tên thuộc tính Kiểu dữ liệu Diễn giải
1 UserID int (4) ID của User, Khóa chính 2 FriendID int (4) ID của Friend, Khóa chính