chat function

main
syneffort 2 years ago
parent a754ba2956
commit a8be3eb3a4
  1. 23
      Chat/Client/ChatRoomForm.cs
  2. 1
      Chat/Client/LoginForm.cs
  3. 6
      Chat/Client/Singleton.cs
  4. 74
      Chat/Core/ChatPacket.cs
  5. 16
      Chat/Core/PServer.cs
  6. 1
      Chat/Core/PacketType.cs

@ -25,17 +25,18 @@ namespace Client
lbxUser.Items.Add(Singleton.Instance.Nickname); lbxUser.Items.Add(Singleton.Instance.Nickname);
Singleton.Instance.UserEnterResponsed += UserEnterResponsed; Singleton.Instance.UserEnterResponsed += UserEnterResponsed;
Singleton.Instance.UserLeaveResponsed += UserLeaveResponsed; Singleton.Instance.UserLeaveResponsed += UserLeaveResponsed;
Singleton.Instance.ChatResponsed += ChatResponsed;
} }
private void btmSend_Click(object sender, EventArgs e) private async void btmSend_Click(object sender, EventArgs e)
{ {
if (string.IsNullOrEmpty(tbxMsg.Text)) if (string.IsNullOrEmpty(tbxMsg.Text))
return; return;
lbxMsg.Items.Add(tbxMsg.Text); ChatPacket packet = new ChatPacket(Singleton.Instance.Nickname, tbxMsg.Text);
tbxMsg.Text = null; await Singleton.Instance.SendAsync(packet.Serialize(), SocketFlags.None);
ScrollMsgToEnd(); tbxMsg.Text = null;
} }
private void ScrollMsgToEnd() private void ScrollMsgToEnd()
@ -83,10 +84,24 @@ namespace Client
}); });
} }
private void ChatResponsed(object? sender, EventArgs e)
{
if (sender == null)
return;
ChatPacket packet = (ChatPacket)sender;
InvokeMethod(() =>
{
lbxMsg.Items.Add($"{packet.NickName}: {packet.Message}");
ScrollMsgToEnd();
});
}
private async void ChatRoomForm_FormClosing(object sender, FormClosingEventArgs e) private async void ChatRoomForm_FormClosing(object sender, FormClosingEventArgs e)
{ {
Singleton.Instance.UserEnterResponsed -= UserEnterResponsed; Singleton.Instance.UserEnterResponsed -= UserEnterResponsed;
Singleton.Instance.UserLeaveResponsed -= UserLeaveResponsed; Singleton.Instance.UserLeaveResponsed -= UserLeaveResponsed;
Singleton.Instance.ChatResponsed -= ChatResponsed;
UserLeavePacket packet = new UserLeavePacket(Singleton.Instance.Nickname); UserLeavePacket packet = new UserLeavePacket(Singleton.Instance.Nickname);
await Singleton.Instance.SendAsync(packet.Serialize(), SocketFlags.None); await Singleton.Instance.SendAsync(packet.Serialize(), SocketFlags.None);

@ -60,6 +60,7 @@ namespace Client
else else
{ {
Singleton.Instance.Socket.Shutdown(SocketShutdown.Send); Singleton.Instance.Socket.Shutdown(SocketShutdown.Send);
MessageBox.Show("Fail to login");
} }
} }
} }

@ -23,6 +23,7 @@ namespace Client
public event EventHandler? EnterRoomResponsed; public event EventHandler? EnterRoomResponsed;
public event EventHandler? UserEnterResponsed; public event EventHandler? UserEnterResponsed;
public event EventHandler? UserLeaveResponsed; public event EventHandler? UserLeaveResponsed;
public event EventHandler? ChatResponsed;
public async Task ConnectAsync(string ip, int port) public async Task ConnectAsync(string ip, int port)
{ {
@ -100,6 +101,11 @@ namespace Client
UserLeavePacket packet = new UserLeavePacket(dataBuffer); UserLeavePacket packet = new UserLeavePacket(dataBuffer);
UserLeaveResponsed?.Invoke(packet, EventArgs.Empty); UserLeaveResponsed?.Invoke(packet, EventArgs.Empty);
} }
else if (packetType == PacketType.Chat)
{
ChatPacket packet = new ChatPacket(dataBuffer);
ChatResponsed?.Invoke(packet, EventArgs.Empty);
}
} }
} }
} }

@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Core
{
public class ChatPacket : IPacket
{
public string Message { get; private set; }
public string NickName { get; private set; }
public ChatPacket(string nickname, string message)
{
NickName = nickname;
Message = message;
}
public ChatPacket(byte[] buffer)
{
int cursor = 2;
short messageSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor));
cursor += sizeof(short);
Message = Encoding.UTF8.GetString(buffer, cursor, messageSize);
cursor += messageSize;
short nicknameSize = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(buffer, cursor));
cursor += sizeof(short);
NickName = Encoding.UTF8.GetString(buffer, cursor, nicknameSize);
}
public byte[] Serialize()
{
// 2bytes header
// data: 2bytes packetType + 2bytes id size + id + 2bytes nickname size + nickname
byte[] packetType = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)PacketType.Chat));
byte[] message = Encoding.UTF8.GetBytes(Message);
byte[] messageSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)message.Length));
byte[] nickname = Encoding.UTF8.GetBytes(NickName);
byte[] nicknameSize = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)nickname.Length));
short dataSize = (short)(packetType.Length + message.Length + messageSize.Length + nickname.Length + nicknameSize.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(messageSize, 0, buffer, cursor, messageSize.Length);
cursor += messageSize.Length;
Array.Copy(message, 0, buffer, cursor, message.Length);
cursor += message.Length;
Array.Copy(nicknameSize, 0, buffer, cursor, nicknameSize.Length);
cursor += nicknameSize.Length;
Array.Copy(nickname, 0, buffer, cursor, nickname.Length);
return buffer;
}
}
}

@ -76,13 +76,13 @@ namespace Core
{ {
LoginRequestPacket requestPacket = new LoginRequestPacket(dataBuffer); LoginRequestPacket requestPacket = new LoginRequestPacket(dataBuffer);
Clients.TryAdd(requestPacket.Id, clientSocket); bool result = Clients.TryAdd(requestPacket.Id, clientSocket);
Console.WriteLine($"[{DateTime.Now}] LoginRequest - Id: {requestPacket.Id}, Nickname: {requestPacket.NickName}"); Console.WriteLine($"[{DateTime.Now}] LoginRequest - Id: {requestPacket.Id}, Nickname: {requestPacket.NickName}");
id = requestPacket.Id; id = requestPacket.Id;
nickname = requestPacket.NickName; nickname = requestPacket.NickName;
LoginResponsePacket responsePacket = new LoginResponsePacket(StatusCode.Success); LoginResponsePacket responsePacket = new LoginResponsePacket(result ? StatusCode.Success : StatusCode.Failed);
await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None); await clientSocket.SendAsync(responsePacket.Serialize(), SocketFlags.None);
} }
else if (packetType == PacketType.CreateRoomRequest) else if (packetType == PacketType.CreateRoomRequest)
@ -169,6 +169,18 @@ namespace Core
} }
} }
} }
else if (packetType == PacketType.Chat)
{
ChatPacket packet = new ChatPacket(dataBuffer);
if (Rooms.TryGetValue(roomName, out var room))
{
foreach (var user in room.Users)
{
if (Clients.TryGetValue(user.Key, out var otherClient))
await otherClient.SendAsync(packet.Serialize(), SocketFlags.None);
}
}
}
} }
} }
} }

@ -18,5 +18,6 @@ namespace Core
EnterRoomResponse, EnterRoomResponse,
UserEnter, UserEnter,
UserLeave, UserLeave,
Chat
} }
} }

Loading…
Cancel
Save