diff --git a/Chat/Client/Singleton.cs b/Chat/Client/Singleton.cs index b6fbbe5..98a6e22 100644 --- a/Chat/Client/Singleton.cs +++ b/Chat/Client/Singleton.cs @@ -44,69 +44,78 @@ namespace Client Socket socket = (Socket)sender; byte[] headerBuffer = new byte[2]; - while (true) + + try { - // header buffer - int n1 = await socket.ReceiveAsync(headerBuffer, SocketFlags.None); - if (n1 < 1) - { - Console.WriteLine($"[{DateTime.Now}] Disconnect server: {socket.RemoteEndPoint}"); - socket.Dispose(); - return; - } - else if (n1 == 1) + while (true) { - await socket.ReceiveAsync(new ArraySegment(headerBuffer, 1, 1), SocketFlags.None); - } + // header buffer + int n1 = await socket.ReceiveAsync(headerBuffer, SocketFlags.None); + if (n1 < 1) + { + Console.WriteLine($"[{DateTime.Now}] Disconnect server: {socket.RemoteEndPoint}"); + socket.Dispose(); + return; + } + else if (n1 == 1) + { + await socket.ReceiveAsync(new ArraySegment(headerBuffer, 1, 1), SocketFlags.None); + } - // data buffer - short dataSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerBuffer)); - byte[] dataBuffer = new byte[dataSize]; + // data buffer + short dataSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerBuffer)); + byte[] dataBuffer = new byte[dataSize]; - int totalRecv = 0; - while (totalRecv < dataSize) - { - int n2 = await socket.ReceiveAsync(new ArraySegment(dataBuffer, totalRecv, dataSize - totalRecv), SocketFlags.None); - totalRecv += n2; - } + int totalRecv = 0; + while (totalRecv < dataSize) + { + int n2 = await socket.ReceiveAsync(new ArraySegment(dataBuffer, totalRecv, dataSize - totalRecv), SocketFlags.None); + totalRecv += n2; + } - PacketType packetType = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer)); - if (packetType == PacketType.LoginResponse) - { - LoginResponsePacket packet = new LoginResponsePacket(dataBuffer); - LoginResponsed?.Invoke(packet, EventArgs.Empty); - } - else if (packetType == PacketType.CreateRoomResponse) - { - CreateRoomResponsePacket packet = new CreateRoomResponsePacket(dataBuffer); - CreateRoomResponsed?.Invoke(packet, EventArgs.Empty); - } - else if (packetType == PacketType.RoomListResponse) - { - 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); - } - else if (packetType == PacketType.UserEnter) - { - UserEnterPacket packet = new UserEnterPacket(dataBuffer); - UserEnterResponsed?.Invoke(packet, EventArgs.Empty); - } - else if (packetType == PacketType.UserLeave) - { - UserLeavePacket packet = new UserLeavePacket(dataBuffer); - UserLeaveResponsed?.Invoke(packet, EventArgs.Empty); - } - else if (packetType == PacketType.Chat) - { - ChatPacket packet = new ChatPacket(dataBuffer); - ChatResponsed?.Invoke(packet, EventArgs.Empty); + PacketType packetType = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer)); + if (packetType == PacketType.LoginResponse) + { + LoginResponsePacket packet = new LoginResponsePacket(dataBuffer); + LoginResponsed?.Invoke(packet, EventArgs.Empty); + } + else if (packetType == PacketType.CreateRoomResponse) + { + CreateRoomResponsePacket packet = new CreateRoomResponsePacket(dataBuffer); + CreateRoomResponsed?.Invoke(packet, EventArgs.Empty); + } + else if (packetType == PacketType.RoomListResponse) + { + 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); + } + else if (packetType == PacketType.UserEnter) + { + UserEnterPacket packet = new UserEnterPacket(dataBuffer); + UserEnterResponsed?.Invoke(packet, EventArgs.Empty); + } + else if (packetType == PacketType.UserLeave) + { + UserLeavePacket packet = new UserLeavePacket(dataBuffer); + UserLeaveResponsed?.Invoke(packet, EventArgs.Empty); + } + else if (packetType == PacketType.Chat) + { + ChatPacket packet = new ChatPacket(dataBuffer); + ChatResponsed?.Invoke(packet, EventArgs.Empty); + } } } + catch (Exception ex) + { + MessageBox.Show(ex.ToString()); + Environment.Exit(1); + } } } } diff --git a/Chat/Core/PServer.cs b/Chat/Core/PServer.cs index 1c046b6..b617926 100644 --- a/Chat/Core/PServer.cs +++ b/Chat/Core/PServer.cs @@ -27,9 +27,16 @@ namespace Core { while (true) { - Socket clientSocket = await serverSocket.AcceptAsync(); - Console.WriteLine($"[{DateTime.Now}] Accept client: {clientSocket.RemoteEndPoint}"); - ThreadPool.QueueUserWorkItem(RunAsync, clientSocket); + try + { + Socket clientSocket = await serverSocket.AcceptAsync(); + Console.WriteLine($"[{DateTime.Now}] Accept client: {clientSocket.RemoteEndPoint}"); + ThreadPool.QueueUserWorkItem(RunAsync, clientSocket); + } + catch (Exception ex) + { + Console.WriteLine(ex); + } } } @@ -45,143 +52,175 @@ namespace Core string nickname = ""; string roomName = ""; - while (true) + try { - // header buffer - int n1 = await clientSocket.ReceiveAsync(headerBuffer, SocketFlags.None); - if (n1 < 1) + while (true) { - Console.WriteLine($"[{DateTime.Now}] Disconnect client - {clientSocket.RemoteEndPoint}"); - clientSocket.Dispose(); - return; - } - else if (n1 == 1) - { - await clientSocket.ReceiveAsync(new ArraySegment(headerBuffer, 1, 1), SocketFlags.None); - } + // header buffer + int n1 = await clientSocket.ReceiveAsync(headerBuffer, SocketFlags.None); + if (n1 < 1) + { + Console.WriteLine($"[{DateTime.Now}] Disconnect client - {clientSocket.RemoteEndPoint}"); + await Remove(id, nickname, roomName, clientSocket); + return; + } + else if (n1 == 1) + { + await clientSocket.ReceiveAsync(new ArraySegment(headerBuffer, 1, 1), SocketFlags.None); + } - // data buffer - short dataSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerBuffer)); - byte[] dataBuffer = new byte[dataSize]; + // data buffer + short dataSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(headerBuffer)); + byte[] dataBuffer = new byte[dataSize]; - int totalRecv = 0; - while (totalRecv < dataSize) - { - int n2 = await clientSocket.ReceiveAsync(new ArraySegment(dataBuffer, totalRecv, dataSize - totalRecv), SocketFlags.None); - totalRecv += n2; - } + int totalRecv = 0; + while (totalRecv < dataSize) + { + int n2 = await clientSocket.ReceiveAsync(new ArraySegment(dataBuffer, totalRecv, dataSize - totalRecv), SocketFlags.None); + totalRecv += n2; + } - PacketType packetType = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer)); - if (packetType == PacketType.LoginRequest) - { - LoginRequestPacket requestPacket = new LoginRequestPacket(dataBuffer); - - bool result = Clients.TryAdd(requestPacket.Id, clientSocket); - Console.WriteLine($"[{DateTime.Now}] LoginRequest - Id: {requestPacket.Id}, Nickname: {requestPacket.NickName}"); + PacketType packetType = (PacketType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(dataBuffer)); + if (packetType == PacketType.LoginRequest) + { + LoginRequestPacket requestPacket = new LoginRequestPacket(dataBuffer); - id = requestPacket.Id; - nickname = requestPacket.NickName; + bool result = Clients.TryAdd(requestPacket.Id, clientSocket); + Console.WriteLine($"[{DateTime.Now}] LoginRequest - Id: {requestPacket.Id}, Nickname: {requestPacket.NickName}"); - LoginResponsePacket responsePacket = new LoginResponsePacket(result ? StatusCode.Success : StatusCode.Failed); - await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); - } - else if (packetType == PacketType.CreateRoomRequest) - { - CreateRoomRequestPacket requestPacket = new CreateRoomRequestPacket(dataBuffer); - Room room = new Room(); - if (Rooms.TryAdd(requestPacket.RoomName, room)) - { - roomName = requestPacket.RoomName; - room.Users.TryAdd(id, nickname); - Console.WriteLine($"[{DateTime.Now}] CreateRoomRequest - RoomName: {roomName}, id: {id}, nickname: {nickname}"); + id = requestPacket.Id; + nickname = requestPacket.NickName; - CreateRoomResponsePacket responsePacket = new CreateRoomResponsePacket(StatusCode.Success); + LoginResponsePacket responsePacket = new LoginResponsePacket(result ? StatusCode.Success : StatusCode.Failed); await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); } - else + else if (packetType == PacketType.CreateRoomRequest) { - Console.WriteLine($"[{DateTime.Now}] CreateRoomRequest failed - RoomName: {requestPacket.RoomName}"); + CreateRoomRequestPacket requestPacket = new CreateRoomRequestPacket(dataBuffer); + Room room = new Room(); + if (Rooms.TryAdd(requestPacket.RoomName, room)) + { + roomName = requestPacket.RoomName; + room.Users.TryAdd(id, nickname); + Console.WriteLine($"[{DateTime.Now}] CreateRoomRequest - RoomName: {roomName}, id: {id}, nickname: {nickname}"); - CreateRoomResponsePacket responsePacket = new CreateRoomResponsePacket(StatusCode.Failed); - await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + CreateRoomResponsePacket responsePacket = new CreateRoomResponsePacket(StatusCode.Success); + await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + } + else + { + Console.WriteLine($"[{DateTime.Now}] CreateRoomRequest failed - RoomName: {requestPacket.RoomName}"); + + CreateRoomResponsePacket responsePacket = new CreateRoomResponsePacket(StatusCode.Failed); + await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + } } - } - else if (packetType == PacketType.RoomListRequest) - { - 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)) + else if (packetType == PacketType.RoomListRequest) { - 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); - - await Task.Delay(100); - foreach (var user in room.Users) + 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)) { - if (user.Value == nickname) - continue; + 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); - // add me to other user - if (Clients.TryGetValue(user.Key, out var otherClient)) + await Task.Delay(100); + foreach (var user in room.Users) { - UserEnterPacket enterPacket = new UserEnterPacket(nickname); - await otherClient.SendAsync(enterPacket.Serialize(), SocketFlags.None); + if (user.Value == nickname) + continue; + + // add me to other user + if (Clients.TryGetValue(user.Key, out var otherClient)) + { + UserEnterPacket enterPacket = new UserEnterPacket(nickname); + await otherClient.SendAsync(enterPacket.Serialize(), SocketFlags.None); + } + + // add other user to me + UserEnterPacket packet = new UserEnterPacket(user.Value); + await clientSocket.SendAsync(packet.Serialize(), SocketFlags.None); } - - // add other user to me - UserEnterPacket packet = new UserEnterPacket(user.Value); - await clientSocket.SendAsync(packet.Serialize(), SocketFlags.None); } - } - else - { - Console.WriteLine($"[{DateTime.Now}] EnterRoomRequest failed - RoomName: {requestPacket.RoomName}"); + else + { + Console.WriteLine($"[{DateTime.Now}] EnterRoomRequest failed - RoomName: {requestPacket.RoomName}"); - EnterRoomResponsePacket responsePacket = new EnterRoomResponsePacket(StatusCode.Failed); - await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + EnterRoomResponsePacket responsePacket = new EnterRoomResponsePacket(StatusCode.Failed); + await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); + } } - } - else if (packetType == PacketType.UserLeave) - { - UserLeavePacket packet = new UserLeavePacket(dataBuffer); - if (Rooms.TryGetValue(roomName, out var room)) + else if (packetType == PacketType.UserLeave) { - room.Users.TryRemove(id, out _); + UserLeavePacket packet = new UserLeavePacket(dataBuffer); + if (Rooms.TryGetValue(roomName, out var room)) + { + room.Users.TryRemove(id, out _); - if (room.Users.IsEmpty) - Rooms.TryRemove(roomName, out _); + if (room.Users.IsEmpty) + Rooms.TryRemove(roomName, out _); - roomName = ""; + roomName = ""; - foreach (var user in room.Users) - { - if (Clients.TryGetValue(user.Key, out var otherClient)) - await otherClient.SendAsync(packet.Serialize(), SocketFlags.None); + foreach (var user in room.Users) + { + if (Clients.TryGetValue(user.Key, out var otherClient)) + await otherClient.SendAsync(packet.Serialize(), SocketFlags.None); + } } } - } - else if (packetType == PacketType.Chat) - { - ChatPacket packet = new ChatPacket(dataBuffer); - if (Rooms.TryGetValue(roomName, out var room)) + else if (packetType == PacketType.Chat) { - foreach (var user in room.Users) + ChatPacket packet = new ChatPacket(dataBuffer); + if (Rooms.TryGetValue(roomName, out var room)) { - if (Clients.TryGetValue(user.Key, out var otherClient)) - await otherClient.SendAsync(packet.Serialize(), SocketFlags.None); + foreach (var user in room.Users) + { + if (Clients.TryGetValue(user.Key, out var otherClient)) + await otherClient.SendAsync(packet.Serialize(), SocketFlags.None); + } } } } } + catch (Exception ex) + { + Console.WriteLine(ex); + await Remove(id, nickname, roomName, clientSocket); + } + } + + private async Task Remove(string id, string nickname, string roomName, Socket clientSocket) + { + Clients.TryRemove(id, out _); + if (Rooms.TryGetValue(roomName, out var room)) + { + UserLeavePacket packet = new UserLeavePacket(nickname); + + room.Users.TryRemove(id, out _); + + if (room.Users.IsEmpty) + Rooms.TryRemove(roomName, out _); + + roomName = ""; + + foreach (var user in room.Users) + { + if (Clients.TryGetValue(user.Key, out var otherClient)) + await otherClient.SendAsync(packet.Serialize(), SocketFlags.None); + } + } + + clientSocket.Dispose(); } } }