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 static Singleton Instance { get; set; } = new Singleton();
public readonly int HEARTBEAT_INTERVAL = 5000;
public string Id { get; set; } = ""; public string Id { get; set; } = "";
public string Nickname { get; set; } = ""; public string Nickname { get; set; } = "";
public Socket Socket { get; } = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); public Socket Socket { get; } = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
@ -45,6 +47,13 @@ namespace Client
Socket socket = (Socket)sender; Socket socket = (Socket)sender;
byte[] headerBuffer = new byte[2]; 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 try
{ {
while (true) while (true)
@ -54,6 +63,8 @@ namespace Client
if (n1 < 1) if (n1 < 1)
{ {
Console.WriteLine($"[{DateTime.Now}] Disconnect server: {socket.RemoteEndPoint}"); Console.WriteLine($"[{DateTime.Now}] Disconnect server: {socket.RemoteEndPoint}");
timer.Stop();
socket.Dispose(); socket.Dispose();
return; return;
} }
@ -78,6 +89,8 @@ namespace Client
{ {
LoginResponsePacket packet = new LoginResponsePacket(dataBuffer); LoginResponsePacket packet = new LoginResponsePacket(dataBuffer);
LoginResponsed?.Invoke(packet, EventArgs.Empty); LoginResponsed?.Invoke(packet, EventArgs.Empty);
timer.Start();
} }
else if (packetType == PacketType.CreateRoomResponse) 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 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); private Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public ConcurrentDictionary<string, Room> Rooms { get; } = new ConcurrentDictionary<string, Room>(); public ConcurrentDictionary<string, Room> Rooms { get; } = new ConcurrentDictionary<string, Room>();
@ -56,8 +59,19 @@ namespace Core
{ {
while (true) while (true)
{ {
Task task1 = Task.Delay(HEARTBEAT_INTERVAL * HEARTBEAT_THREASHOLD);
// header buffer // 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) if (n1 < 1)
{ {
Console.WriteLine($"[{DateTime.Now}] Disconnect client - {clientSocket.RemoteEndPoint}"); 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) catch (Exception ex)

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

Loading…
Cancel
Save