main
syneffort 2 years ago
parent c39b6adf3d
commit 72ac49e867
  1. 13
      Chat/Client/Singleton.cs
  2. 30
      Chat/Core/HeartbeatPacket.cs
  3. 20
      Chat/Core/PServer.cs
  4. 3
      Chat/Core/PacketType.cs

@ -13,6 +13,8 @@ namespace Client
{
public static Singleton Instance { get; set; } = new Singleton();
public readonly int HEARTBEAT_INTERVAL = 5000;
public string Id { get; set; } = "";
public string Nickname { get; set; } = "";
public Socket Socket { get; } = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
@ -45,6 +47,13 @@ namespace Client
Socket socket = (Socket)sender;
byte[] headerBuffer = new byte[2];
System.Timers.Timer timer = new System.Timers.Timer(HEARTBEAT_INTERVAL);
timer.Elapsed += async (sender, e) =>
{
HeartbeatPacket packet = new HeartbeatPacket();
await socket.SendAsync(packet.Serialize(), SocketFlags.None);
};
try
{
while (true)
@ -54,6 +63,8 @@ namespace Client
if (n1 < 1)
{
Console.WriteLine($"[{DateTime.Now}] Disconnect server: {socket.RemoteEndPoint}");
timer.Stop();
socket.Dispose();
return;
}
@ -78,6 +89,8 @@ namespace Client
{
LoginResponsePacket packet = new LoginResponsePacket(dataBuffer);
LoginResponsed?.Invoke(packet, EventArgs.Empty);
timer.Start();
}
else if (packetType == PacketType.CreateRoomResponse)
{

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Core
{
public class HeartbeatPacket : IPacket
{
public byte[] Serialize()
{
byte[] packetType = BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)PacketType.Heartbeat));
short dataSize = (short)(packetType.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);
return buffer;
}
}
}

@ -11,6 +11,9 @@ namespace Core
{
public class PServer
{
private readonly int HEARTBEAT_INTERVAL = 5000;
private readonly int HEARTBEAT_THREASHOLD = 5;
private Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public ConcurrentDictionary<string, Room> Rooms { get; } = new ConcurrentDictionary<string, Room>();
@ -56,8 +59,19 @@ namespace Core
{
while (true)
{
Task task1 = Task.Delay(HEARTBEAT_INTERVAL * HEARTBEAT_THREASHOLD);
// header buffer
int n1 = await clientSocket.ReceiveAsync(headerBuffer, SocketFlags.None);
Task<int> task2 = clientSocket.ReceiveAsync(headerBuffer, SocketFlags.None);
Task result = await Task.WhenAny(task1, task2);
if (result == task1)
{
Console.WriteLine($"[{DateTime.Now}] Disconnect client - {clientSocket.RemoteEndPoint}");
await Remove(id, nickname, roomName, clientSocket);
return;
}
int n1 = await task2;
if (n1 < 1)
{
Console.WriteLine($"[{DateTime.Now}] Disconnect client - {clientSocket.RemoteEndPoint}");
@ -195,6 +209,10 @@ namespace Core
}
}
}
else if (packetType == PacketType.Heartbeat)
{
Console.WriteLine($"[{DateTime.Now}] Heartbeat from client - {clientSocket.RemoteEndPoint} (id: {id}, nickname: {nickname})");
}
}
}
catch (Exception ex)

@ -19,6 +19,7 @@ namespace Core
UserEnter,
UserLeave,
Chat,
Duplicate
Duplicate,
Heartbeat,
}
}

Loading…
Cancel
Save