feat : 에코 서버 / 클라이언트 기능 추가 작업
This commit is contained in:
@@ -1,17 +1,20 @@
|
|||||||
using LiteNetLib.Utils;
|
using LiteNetLib;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace ClientTester.EchoDummyService;
|
namespace ClientTester.EchoDummyService;
|
||||||
|
|
||||||
public class DummyClientService
|
public class DummyClientService
|
||||||
{
|
{
|
||||||
private readonly List<DummyClients> _clients;
|
private readonly List<DummyClients> clients;
|
||||||
private readonly int _sendInterval;
|
private readonly int sendInterval;
|
||||||
|
|
||||||
|
// 모든거 강종
|
||||||
|
public event Action? OnAllDisconnected;
|
||||||
|
|
||||||
public DummyClientService(int count, string ip, int port, string key, int sendIntervalMs = 1000)
|
public DummyClientService(int count, string ip, int port, string key, int sendIntervalMs = 1000)
|
||||||
{
|
{
|
||||||
_sendInterval = sendIntervalMs;
|
sendInterval = sendIntervalMs;
|
||||||
_clients = Enumerable.Range(0, count)
|
clients = Enumerable.Range(0, count)
|
||||||
.Select(i => new DummyClients(i, ip, port, key))
|
.Select(i => new DummyClients(i, ip, port, key))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
@@ -30,62 +33,100 @@ public class DummyClientService
|
|||||||
{
|
{
|
||||||
while (!ct.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
foreach (var c in _clients)
|
foreach (DummyClients c in clients)
|
||||||
|
{
|
||||||
c.PollEvents();
|
c.PollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
try { await Task.Delay(15, ct); }
|
try
|
||||||
catch (OperationCanceledException) { break; }
|
{
|
||||||
|
await Task.Delay(15, ct);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendLoopAsync(CancellationToken ct)
|
private async Task SendLoopAsync(CancellationToken ct)
|
||||||
{
|
{
|
||||||
try { await Task.Delay(500, ct); }
|
try
|
||||||
catch (OperationCanceledException) { return; }
|
{
|
||||||
|
await Task.Delay(500, ct);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int tick = 0;
|
int tick = 0;
|
||||||
|
|
||||||
while (!ct.IsCancellationRequested)
|
while (!ct.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
int sent = 0;
|
int sent = 0;
|
||||||
|
int total = clients.Count;
|
||||||
|
|
||||||
foreach (var client in _clients)
|
foreach (DummyClients client in clients)
|
||||||
{
|
{
|
||||||
client.SendPing();
|
client.SendPing();
|
||||||
if (client.Peer != null) sent++;
|
if (client.peer != null)
|
||||||
|
{
|
||||||
|
sent++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
total--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Information("[TICK {Tick:000}] {Sent}/{Total} 전송", tick, sent, _clients.Count);
|
if (total == 0)
|
||||||
|
{
|
||||||
|
Log.Information("All Disconnect Clients");
|
||||||
|
OnAllDisconnected?.Invoke();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.Information("[TICK {Tick:000}] {Sent}/{Total} 전송", tick, sent, total);
|
||||||
tick++;
|
tick++;
|
||||||
|
|
||||||
try { await Task.Delay(_sendInterval, ct); }
|
try
|
||||||
catch (OperationCanceledException) { break; }
|
{
|
||||||
|
await Task.Delay(sendInterval, ct);
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrintStats()
|
public void PrintStats()
|
||||||
{
|
{
|
||||||
int totalSent = 0, totalRecv = 0;
|
int totalSent = 0, totalRecv = 0;
|
||||||
int connected = 0;
|
int connected = 0;
|
||||||
|
|
||||||
Log.Information("════════════ Performance Report ════════════");
|
Log.Information("───────────── Performance Report ─────────────");
|
||||||
|
|
||||||
double totalAvgRtt = 0;
|
double totalAvgRtt = 0;
|
||||||
|
|
||||||
foreach (var c in _clients)
|
foreach (DummyClients c in clients)
|
||||||
{
|
{
|
||||||
var stats = c.Peer?.Statistics;
|
NetStatistics? stats = c.peer?.Statistics;
|
||||||
long loss = stats?.PacketLoss ?? 0;
|
long loss = stats?.PacketLoss ?? 0;
|
||||||
float lossPct = stats?.PacketLossPercent ?? 0f;
|
float lossPct = stats?.PacketLossPercent ?? 0f;
|
||||||
|
|
||||||
Log.Information(
|
Log.Information(
|
||||||
"[Client {ClientId:00}] Sent={Sent} Recv={Recv} | Loss={Loss}({LossPct:F1}%) AvgRTT={AvgRtt:F3}ms LastRTT={LastRtt:F3}ms",
|
"[Client {ClientId:00}] Sent={Sent} Recv={Recv} | Loss={Loss}({LossPct:F1}%) AvgRTT={AvgRtt:F3}ms LastRTT={LastRtt:F3}ms",
|
||||||
c.ClientId, c.SentCount, c.ReceivedCount, loss, lossPct, c.AvgRttMs, c.LastRttMs);
|
c.clientId, c.SentCount, c.ReceivedCount, loss, lossPct, c.AvgRttMs, c.LastRttMs);
|
||||||
|
|
||||||
totalSent += c.SentCount;
|
totalSent += c.SentCount;
|
||||||
totalRecv += c.ReceivedCount;
|
totalRecv += c.ReceivedCount;
|
||||||
totalAvgRtt += c.AvgRttMs;
|
totalAvgRtt += c.AvgRttMs;
|
||||||
if (c.Peer != null) connected++;
|
if (c.peer != null)
|
||||||
|
{
|
||||||
|
connected++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double avgRtt = connected > 0 ? totalAvgRtt / connected : 0;
|
double avgRtt = connected > 0 ? totalAvgRtt / connected : 0;
|
||||||
@@ -93,14 +134,16 @@ public class DummyClientService
|
|||||||
Log.Information("────────────────────────────────────────────");
|
Log.Information("────────────────────────────────────────────");
|
||||||
Log.Information(
|
Log.Information(
|
||||||
"[TOTAL] Sent={Sent} Recv={Recv} Connected={Connected}/{Total} AvgRTT={AvgRtt:F3}ms",
|
"[TOTAL] Sent={Sent} Recv={Recv} Connected={Connected}/{Total} AvgRTT={AvgRtt:F3}ms",
|
||||||
totalSent, totalRecv, connected, _clients.Count, avgRtt);
|
totalSent, totalRecv, connected, clients.Count, avgRtt);
|
||||||
Log.Information("════════════════════════════════════════════");
|
Log.Information("────────────────────────────────────────────");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Stop()
|
||||||
{
|
{
|
||||||
foreach (var c in _clients)
|
foreach (DummyClients c in clients)
|
||||||
|
{
|
||||||
c.Stop();
|
c.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
Log.Information("[SERVICE] 모든 클라이언트 종료됨.");
|
Log.Information("[SERVICE] 모든 클라이언트 종료됨.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using ClientTester.Packet;
|
||||||
using LiteNetLib;
|
using LiteNetLib;
|
||||||
using LiteNetLib.Utils;
|
using LiteNetLib.Utils;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@@ -7,82 +8,112 @@ namespace ClientTester.EchoDummyService;
|
|||||||
|
|
||||||
public class DummyClients
|
public class DummyClients
|
||||||
{
|
{
|
||||||
public NetManager Manager;
|
public NetManager manager;
|
||||||
public EventBasedNetListener Listener;
|
public EventBasedNetListener listener;
|
||||||
public NetPeer? Peer;
|
public NetPeer? peer;
|
||||||
public int ClientId;
|
public int clientId;
|
||||||
|
|
||||||
// seq → 송신 타임스탬프 (Stopwatch tick)
|
// seq → 송신 타임스탬프 (Stopwatch tick)
|
||||||
private readonly Dictionary<int, long> _pendingPings = new();
|
private readonly Dictionary<int, long> pendingPings = new();
|
||||||
private int _seqNumber;
|
private int seqNumber;
|
||||||
|
|
||||||
// 통계
|
// 통계
|
||||||
public int SentCount;
|
public int SentCount
|
||||||
public int ReceivedCount;
|
{
|
||||||
public double LastRttMs;
|
set;
|
||||||
public double TotalRttMs;
|
get;
|
||||||
public int RttCount;
|
}
|
||||||
|
public int ReceivedCount
|
||||||
|
{
|
||||||
|
set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
public double LastRttMs
|
||||||
|
{
|
||||||
|
set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
public double TotalRttMs
|
||||||
|
{
|
||||||
|
set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
public int RttCount
|
||||||
|
{
|
||||||
|
set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
public DummyClients(int clientId, string ip, int port, string key)
|
public DummyClients(int clientId, string ip, int port, string key)
|
||||||
{
|
{
|
||||||
ClientId = clientId;
|
this.clientId = clientId;
|
||||||
Listener = new EventBasedNetListener();
|
listener = new EventBasedNetListener();
|
||||||
Manager = new NetManager(Listener);
|
manager = new NetManager(listener);
|
||||||
|
|
||||||
Listener.PeerConnectedEvent += peer =>
|
listener.PeerConnectedEvent += netPeer =>
|
||||||
{
|
{
|
||||||
Peer = peer;
|
peer = netPeer;
|
||||||
Log.Information("[Client {ClientId:00}] 연결됨", ClientId);
|
Log.Information("[Client {ClientId:00}] 연결됨", this.clientId);
|
||||||
};
|
};
|
||||||
|
|
||||||
Listener.NetworkReceiveEvent += (peer, reader, channel, deliveryMethod) =>
|
listener.NetworkReceiveEvent += (peer, reader, channel, deliveryMethod) =>
|
||||||
{
|
{
|
||||||
var msg = reader.GetString();
|
string? msg = reader.GetString();
|
||||||
|
|
||||||
// "ack:seq:{seqNum}" 파싱
|
string[] parts = msg.Split(':');
|
||||||
var parts = msg.Split(':');
|
if (parts.Length == 3 && parts[0] == "ack" && parts[1] == "seq" && int.TryParse(parts[2], out int seq) && pendingPings.TryGetValue(seq, out long sentTick))
|
||||||
if (parts.Length == 3 && parts[0] == "ack" && parts[1] == "seq"
|
|
||||||
&& int.TryParse(parts[2], out int seq)
|
|
||||||
&& _pendingPings.TryGetValue(seq, out long sentTick))
|
|
||||||
{
|
{
|
||||||
double rttMs = (Stopwatch.GetTimestamp() - sentTick)
|
double rttMs = (Stopwatch.GetTimestamp() - sentTick) * 1000.0 / Stopwatch.Frequency;
|
||||||
* 1000.0 / Stopwatch.Frequency;
|
|
||||||
LastRttMs = rttMs;
|
LastRttMs = rttMs;
|
||||||
TotalRttMs += rttMs;
|
TotalRttMs += rttMs;
|
||||||
RttCount++;
|
RttCount++;
|
||||||
_pendingPings.Remove(seq);
|
pendingPings.Remove(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceivedCount++;
|
ReceivedCount++;
|
||||||
reader.Recycle();
|
reader.Recycle();
|
||||||
};
|
};
|
||||||
|
|
||||||
Listener.PeerDisconnectedEvent += (peer, info) =>
|
listener.PeerDisconnectedEvent += (peer, info) =>
|
||||||
{
|
{
|
||||||
Log.Warning("[Client {ClientId:00}] 연결 끊김: {Reason}", ClientId, info.Reason);
|
Log.Warning("[Client {ClientId:00}] 연결 끊김: {Reason}", this.clientId, info.Reason);
|
||||||
Peer = null;
|
this.peer = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
Manager.Start();
|
manager.Start();
|
||||||
Manager.Connect(ip, port, key);
|
manager.Connect(ip, port, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendPing()
|
public void SendPing()
|
||||||
{
|
{
|
||||||
if (Peer is null) return;
|
if (peer == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int seq = _seqNumber++;
|
int seq = seqNumber++;
|
||||||
_pendingPings[seq] = Stopwatch.GetTimestamp();
|
pendingPings[seq] = Stopwatch.GetTimestamp();
|
||||||
|
|
||||||
var writer = new NetDataWriter();
|
NetDataWriter writer = new NetDataWriter();
|
||||||
writer.Put($"seq:{seq}");
|
PacketHeader packetHeader = new PacketHeader();
|
||||||
Peer.Send(writer, DeliveryMethod.ReliableOrdered);
|
packetHeader.Code = 0;
|
||||||
|
packetHeader.BodyLength = $"seq:{seq}".Length;
|
||||||
|
writer.Put((short)packetHeader.Code);
|
||||||
|
writer.Put((short)packetHeader.BodyLength);
|
||||||
|
writer.Put($"Echo seq:{seq}");
|
||||||
|
peer.Send(writer, DeliveryMethod.ReliableOrdered);
|
||||||
SentCount++;
|
SentCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double AvgRttMs => RttCount > 0 ? TotalRttMs / RttCount : 0.0;
|
public double AvgRttMs => RttCount > 0 ? TotalRttMs / RttCount : 0.0;
|
||||||
|
|
||||||
public void PollEvents() => Manager.PollEvents();
|
public void PollEvents()
|
||||||
|
{
|
||||||
|
manager.PollEvents();
|
||||||
|
}
|
||||||
|
|
||||||
public void Stop() => Manager.Stop();
|
public void Stop()
|
||||||
|
{
|
||||||
|
manager.Stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
#pragma warning disable CS8618
|
||||||
|
|
||||||
using ProtoBuf;
|
using ProtoBuf;
|
||||||
|
|
||||||
namespace ClientTester.Packet;
|
namespace ClientTester.Packet;
|
||||||
@@ -164,7 +166,7 @@ public class IntoLobbyPacket
|
|||||||
{
|
{
|
||||||
get;
|
get;
|
||||||
set;
|
set;
|
||||||
}
|
} = null!;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EXIT_LOBBY
|
// EXIT_LOBBY
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace ClientTester.Packet;
|
namespace ClientTester.Packet;
|
||||||
|
|
||||||
public enum PacketCode
|
public enum PacketCode : short
|
||||||
{
|
{
|
||||||
NONE,
|
NONE,
|
||||||
// 초기 클라이언트 시작시 jwt토큰 받아옴
|
// 초기 클라이언트 시작시 jwt토큰 받아옴
|
||||||
|
|||||||
@@ -1,28 +1,37 @@
|
|||||||
using ClientTester.EchoDummyService;
|
using ClientTester.EchoDummyService;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
Log.Logger = new LoggerConfiguration()
|
class EcoClientTester
|
||||||
.WriteTo.Console()
|
|
||||||
.CreateLogger();
|
|
||||||
|
|
||||||
const string SERVER_IP = "localhost";
|
|
||||||
const int SERVER_PORT = 9500;
|
|
||||||
const string CONNECTION_KEY = "game";
|
|
||||||
const int CLIENT_COUNT = 1000;
|
|
||||||
|
|
||||||
var cts = new CancellationTokenSource();
|
|
||||||
Console.CancelKeyPress += (_, e) =>
|
|
||||||
{
|
{
|
||||||
e.Cancel = true;
|
public static readonly string SERVER_IP = "localhost";
|
||||||
Log.Warning("[SHUTDOWN] Ctrl+C 감지, 종료 중...");
|
public static readonly int SERVER_PORT = 9500;
|
||||||
cts.Cancel();
|
public static readonly string CONNECTION_KEY = "test";
|
||||||
};
|
public static readonly int CLIENT_COUNT = 100;
|
||||||
|
|
||||||
var service = new DummyClientService(CLIENT_COUNT, SERVER_IP, SERVER_PORT, CONNECTION_KEY, 100);
|
private static async Task Main(string[] args)
|
||||||
|
{
|
||||||
|
Log.Logger = new LoggerConfiguration().WriteTo.Console().CreateLogger();
|
||||||
|
|
||||||
await service.RunAsync(cts.Token);
|
CancellationTokenSource cts = new CancellationTokenSource();
|
||||||
|
Console.CancelKeyPress += (_, e) =>
|
||||||
|
{
|
||||||
|
e.Cancel = true;
|
||||||
|
Log.Warning("[SHUTDOWN] Ctrl+C 감지, 종료 중...");
|
||||||
|
cts.Cancel();
|
||||||
|
};
|
||||||
|
|
||||||
service.PrintStats();
|
DummyClientService service = new DummyClientService(CLIENT_COUNT, SERVER_IP, SERVER_PORT, CONNECTION_KEY, 100);
|
||||||
service.Stop();
|
service.OnAllDisconnected += async () =>
|
||||||
|
{
|
||||||
|
Log.Warning("[SHUTDOWN] 종료 이벤트 발생, 종료 중...");
|
||||||
|
await cts.CancelAsync();
|
||||||
|
};
|
||||||
|
|
||||||
Log.CloseAndFlush();
|
await service.RunAsync(cts.Token);
|
||||||
|
|
||||||
|
service.PrintStats();
|
||||||
|
service.Stop();
|
||||||
|
|
||||||
|
await Log.CloseAndFlushAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
|
<LangVersion>13</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
#pragma warning disable CS8618
|
||||||
|
|
||||||
using ProtoBuf;
|
using ProtoBuf;
|
||||||
|
|
||||||
namespace ClientTester.Packet;
|
namespace MMOserver.Packet;
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 공통 타입
|
// 공통 타입
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace ClientTester.Packet;
|
namespace MMOserver.Packet;
|
||||||
|
|
||||||
public enum PacketCode
|
public enum PacketCode : short
|
||||||
{
|
{
|
||||||
NONE,
|
NONE,
|
||||||
// 초기 클라이언트 시작시 jwt토큰 받아옴
|
// 초기 클라이언트 시작시 jwt토큰 받아옴
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
using MMOserver.Game;
|
using MMOserver.Game;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
namespace MMOserver;
|
||||||
|
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
private static void Main()
|
private static void Main()
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
using ProtoBuf;
|
using ProtoBuf;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<LangVersion>13</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
|
using System.Threading;
|
||||||
using LiteNetLib;
|
using LiteNetLib;
|
||||||
using LiteNetLib.Utils;
|
using LiteNetLib.Utils;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
@@ -122,6 +125,13 @@ public abstract class ServerBase : INetEventListener
|
|||||||
{
|
{
|
||||||
(ushort type, ushort size, byte[] payload) = PacketSerializer.Deserialize(data);
|
(ushort type, ushort size, byte[] payload) = PacketSerializer.Deserialize(data);
|
||||||
|
|
||||||
|
// 0이라면 에코 서버 테스트용 따로 처리
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
HandleEcho(peer, payload);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Auth 패킷은 베이스에서 처리 (raw 8-byte long, protobuf 불필요)
|
// Auth 패킷은 베이스에서 처리 (raw 8-byte long, protobuf 불필요)
|
||||||
if (type == (ushort)PacketType.Auth)
|
if (type == (ushort)PacketType.Auth)
|
||||||
{
|
{
|
||||||
@@ -167,16 +177,33 @@ public abstract class ServerBase : INetEventListener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Echo 서버 테스트
|
||||||
|
|
||||||
|
private void HandleEcho(NetPeer peer, byte[] payload)
|
||||||
|
{
|
||||||
|
// if (payload.Length < sizeof(long))
|
||||||
|
// {
|
||||||
|
// Log.Warning("[Server] Echo 페이로드 크기 오류 PeerId={Id}", peer.Id);
|
||||||
|
// peer.Disconnect();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 세션에 넣지는 않는다.
|
||||||
|
NetDataReader reader = new NetDataReader(payload);
|
||||||
|
Log.Debug("[Echo] : addr={Addr}, str={Str}", peer.Address, reader.GetString());
|
||||||
|
SendTo(peer, payload);
|
||||||
|
}
|
||||||
|
|
||||||
// ─── Auth 처리 (내부) ────────────────────────────────────────────────
|
// ─── Auth 처리 (내부) ────────────────────────────────────────────────
|
||||||
|
|
||||||
private void HandleAuth(NetPeer peer, byte[] payload)
|
private void HandleAuth(NetPeer peer, byte[] payload)
|
||||||
{
|
{
|
||||||
if (payload.Length < sizeof(long))
|
// if (payload.Length < sizeof(long))
|
||||||
{
|
// {
|
||||||
Log.Warning("[Server] Auth 페이로드 크기 오류 PeerId={Id}", peer.Id);
|
// Log.Warning("[Server] Auth 페이로드 크기 오류 PeerId={Id}", peer.Id);
|
||||||
peer.Disconnect();
|
// peer.Disconnect();
|
||||||
return;
|
// return;
|
||||||
}
|
// }
|
||||||
|
|
||||||
long hashKey = BitConverter.ToInt64(payload, 0);
|
long hashKey = BitConverter.ToInt64(payload, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
namespace ServerLib.Service;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace ServerLib.Service;
|
||||||
|
|
||||||
public class SessionManager
|
public class SessionManager
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user