diff --git a/Chat/Client/RoomListForm.cs b/Chat/Client/RoomListForm.cs index 3017895..e10874e 100644 --- a/Chat/Client/RoomListForm.cs +++ b/Chat/Client/RoomListForm.cs @@ -25,10 +25,11 @@ namespace Client private void InitInstance() { Singleton.Instance.CreateRoomResponsed += CreateRoomResponsed; - Singleton.Instance.RoomListResponsed += Instance_RoomListResponsed; + Singleton.Instance.RoomListResponsed += RoomListResponsed; + Singleton.Instance.EnterRoomResponsed += EnterRoomResponsed; } - private void btnEnter_Click(object sender, EventArgs e) + private async void btnEnter_Click(object sender, EventArgs e) { if (lbxRoom.SelectedItem == null) { @@ -36,14 +37,8 @@ namespace Client return; } - IAsyncResult ar = null; - ar = BeginInvoke(() => - { - ChatRoomForm chatRoomForm = new ChatRoomForm(); - chatRoomForm.Text = lbxRoom.SelectedItem.ToString(); - chatRoomForm.ShowDialog(); - EndInvoke(ar); - }); + EnterRoomRequestPacket packet = new EnterRoomRequestPacket(lbxRoom.SelectedItem.ToString()); + await Singleton.Instance.SendAsync(packet.Serialize(), SocketFlags.None); } private async void btnCreate_Click(object sender, EventArgs e) @@ -105,7 +100,7 @@ namespace Client } } - private void Instance_RoomListResponsed(object? sender, EventArgs e) + private void RoomListResponsed(object? sender, EventArgs e) { if (sender == null) return; @@ -120,6 +115,25 @@ namespace Client }); } + private void EnterRoomResponsed(object? sender, EventArgs e) + { + if (sender == null) + return; + + EnterRoomResponsePacket packet = (EnterRoomResponsePacket)sender; + InvokeMethod(() => + { + IAsyncResult ar = null; + ar = BeginInvoke(() => + { + ChatRoomForm chatRoomForm = new ChatRoomForm(); + chatRoomForm.Text = lbxRoom.SelectedItem.ToString(); + chatRoomForm.ShowDialog(); + EndInvoke(ar); + }); + }); + } + private async void btnRefresh_Click(object sender, EventArgs e) { lbxRoom.Items.Clear(); @@ -130,7 +144,9 @@ namespace Client private void RoomListForm_FormClosing(object sender, FormClosingEventArgs e) { Singleton.Instance.CreateRoomResponsed -= CreateRoomResponsed; - Singleton.Instance.RoomListResponsed -= Instance_RoomListResponsed; + Singleton.Instance.RoomListResponsed -= RoomListResponsed; + Singleton.Instance.EnterRoomResponsed -= EnterRoomResponsed; + Singleton.Instance.Socket.Shutdown(SocketShutdown.Send); } } diff --git a/Chat/Client/Singleton.cs b/Chat/Client/Singleton.cs index 707202b..b7b511b 100644 --- a/Chat/Client/Singleton.cs +++ b/Chat/Client/Singleton.cs @@ -20,6 +20,7 @@ namespace Client public event EventHandler? LoginResponsed; public event EventHandler? CreateRoomResponsed; public event EventHandler? RoomListResponsed; + public event EventHandler? EnterRoomResponsed; public async Task ConnectAsync(string ip, int port) { @@ -82,6 +83,11 @@ namespace Client RoomListResponsePacket packet = new RoomListResponsePacket(dataBuffer); RoomListResponsed?.Invoke(packet, EventArgs.Empty); } + else if (packetType == PacketType.EnterRoomResponse) + { + EnterRoomResponsePacket packet = new EnterRoomResponsePacket(dataBuffer); + EnterRoomResponsed?.Invoke(packet, EventArgs.Empty); + } } } } diff --git a/Chat/Core/EnterRoomRequestPacket.cs b/Chat/Core/EnterRoomRequestPacket.cs new file mode 100644 index 0000000..0ac5561 --- /dev/null +++ b/Chat/Core/EnterRoomRequestPacket.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Core +{ + public class EnterRoomRequestPacket : IPacket + { + public string RoomName { get; private set; } + + public EnterRoomRequestPacket(string roomName) + { + RoomName = roomName; + } + + public EnterRoomRequestPacket(byte[] buffer) + { + int cursor = 2; + + short roomNameSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor)); + cursor += sizeof(short); + + RoomName = Encoding.UTF8.GetString(buffer, cursor, roomNameSize); + } + + public byte[] Serialize() + { + // 2bytes header + // data: 2bytes packetType + 2bytes id size + id + 2bytes nickname size + nickname + + byte[] packetType = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)PacketType.EnterRoomRequest)); + byte[] roomName = Encoding.UTF8.GetBytes(RoomName); + byte[] roomNameSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)roomName.Length)); + + short dataSize = (short)(packetType.Length + roomName.Length + roomNameSize.Length); + byte[] header = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(dataSize)); + + byte[] buffer = new byte[2 + dataSize]; + + int cursor = 0; + Array.Copy(header, 0, buffer, cursor, header.Length); + cursor += header.Length; + + Array.Copy(packetType, 0, buffer, cursor, packetType.Length); + cursor += packetType.Length; + + Array.Copy(roomNameSize, 0, buffer, cursor, roomNameSize.Length); + cursor += roomNameSize.Length; + + Array.Copy(roomName, 0, buffer, cursor, roomName.Length); + + return buffer; + } + } +} diff --git a/Chat/Core/EnterRoomResponsePacket.cs b/Chat/Core/EnterRoomResponsePacket.cs new file mode 100644 index 0000000..d09e39f --- /dev/null +++ b/Chat/Core/EnterRoomResponsePacket.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace Core +{ + public class EnterRoomResponsePacket : IPacket + { + public StatusCode Code { get; set; } + + public EnterRoomResponsePacket(StatusCode code) + { + Code = code; + } + + public EnterRoomResponsePacket(byte[] buffer) + { + Code = (StatusCode)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 2)); + } + + public byte[] Serialize() + { + // 2bytes header + // data: 2bytes packetType + code + + byte[] packetType = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)PacketType.EnterRoomResponse)); + byte[] code = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((int)Code)); + + short dataSize = (short)(packetType.Length + code.Length); + byte[] header = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(dataSize)); + + byte[] buffer = new byte[2 + dataSize]; + + int cursor = 0; + Array.Copy(header, 0, buffer, cursor, header.Length); + cursor += header.Length; + + Array.Copy(packetType, 0, buffer, cursor, packetType.Length); + cursor += packetType.Length; + + Array.Copy(code, 0, buffer, cursor, code.Length); + + return buffer; + } + } +} diff --git a/Chat/Core/PServer.cs b/Chat/Core/PServer.cs index caa87b1..1b7a2f9 100644 --- a/Chat/Core/PServer.cs +++ b/Chat/Core/PServer.cs @@ -90,7 +90,7 @@ namespace Core { roomName = requestPacket.RoomName; room.Users.TryAdd(id, nickname); - Console.WriteLine($"[{DateTime.Now}] CreateRoomRequest - RoomName: {roomName}"); + Console.WriteLine($"[{DateTime.Now}] CreateRoomRequest - RoomName: {roomName}, id: {id}, nickname: {nickname}"); CreateRoomResponsePacket responsePacket = new CreateRoomResponsePacket(StatusCode.Success); await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); @@ -108,6 +108,27 @@ namespace Core RoomListResponsePacket packet = new RoomListResponsePacket(Rooms.Keys); await clientSocket.SendAsync(packet.Serialize(), SocketFlags.None); } + else if (packetType == PacketType.EnterRoomRequest) + { + EnterRoomRequestPacket requestPacket = new EnterRoomRequestPacket(dataBuffer); + if (Rooms.TryGetValue(requestPacket.RoomName, out var room)) + { + roomName = requestPacket.RoomName; + room.Users.TryAdd(id, nickname); + Console.WriteLine($"[{DateTime.Now}] EnterRoomRequest - RoomName: {roomName}, id: {id}, nickname: {nickname}"); + + EnterRoomResponsePacket responsePacket = new EnterRoomResponsePacket(StatusCode.Success); + await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + } + else + { + Console.WriteLine($"[{DateTime.Now}] EnterRoomRequest failed - RoomName: {requestPacket.RoomName}"); + + EnterRoomResponsePacket responsePacket = new EnterRoomResponsePacket(StatusCode.Failed); + await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + + } + } } } } diff --git a/Chat/Core/PacketType.cs b/Chat/Core/PacketType.cs index 8911fc5..cd37c0f 100644 --- a/Chat/Core/PacketType.cs +++ b/Chat/Core/PacketType.cs @@ -14,5 +14,9 @@ namespace Core CreateRoomResponse, RoomListRequest, RoomListResponse, + EnterRoomRequest, + EnterRoomResponse, + UserEnter, + UserLeave, } }