public override void OnRecvPacket(ArraySegment<byte> buffer)
{
PacketManager.Instance.OnRecvPacket(this, buffer);
}
namespace Server
{
class PacketManager
{
#region Singleton
static PacketManager _instance;
public static PacketManager Instance
{
get
{
if (_instance == null)
_instance = new PacketManager();
return _instance;
}
}
#endregion
매니저를 싱글톤 패턴으로 사용한다.
Dictionary<ushort, Action<PacketSession, ArraySegment<byte>>> _onRecv = new Dictionary<ushort, Action<PacketSession, ArraySegment<byte>>>();
Dictionary<ushort, Action<PacketSession, IPacket>> _handler = new Dictionary<ushort, Action<PacketSession, IPacket>>();
public void Register()
{
_onRecv.Add((ushort)PacketID.PlayerInfoReq, makePacket<PlayerInfoReq>);
_handler.Add((ushort)PacketID.PlayerInfoReq, PacketHandler.PlayerInfoReqHandler);
}
기존의 switch문으로 패킷 종류에 따라 사용하는 것은 시간이 걸리므로 Dictionary 타입으로 전환하였다.
Register 함수를 통해 packetID에 대응하는 action을 지정하도록 하였다.
public void OnRecvPacket(PacketSession session, ArraySegment<byte> buffer)
{
ushort count = 0;
ushort size = BitConverter.ToUInt16(buffer.Array, buffer.Offset);
count += 2;
ushort id = BitConverter.ToUInt16(buffer.Array, buffer.Offset + count);
count += 2;
Action<PacketSession, ArraySegment<byte>> action = null;
if (_onRecv.TryGetValue(id, out action))
action.Invoke(session, buffer);
}
ClientSession에서 사용되는 코드이다.
_onRecv에서 TryGetValue를 하여 Register에서 등록한 action (makePacket)을 실행시킨다.
void makePacket<T>(PacketSession session, ArraySegment<byte> buffer) where T : IPacket, new()
{
T pkt = new T();
pkt.Read(buffer);
Action<PacketSession, IPacket> action = null;
if (_handler.TryGetValue(pkt.Protocol, out action))
action.Invoke(session, pkt);
}
}
}
패킷을 생성하여 읽는 작업을 실시한다.
여기서는 핸들러에 등록된 Action을 실행하는데, 해당 함수는 PacketHandler.cs에 작성되어 있다.
namespace Server
{
class PacketHandler
{
public static void PlayerInfoReqHandler(PacketSession session, IPacket packet)
{
PlayerInfoReq p = packet as PlayerInfoReq;
Console.WriteLine($"PlayerInfoReq: {p.playerId} {p.name}");
foreach (PlayerInfoReq.Skill skill in p.skills)
{
Console.WriteLine($"Skill ({skill.id}) ({skill.level}) ({skill.duration})");
}
}
}
}
PacketManager.cs에서 _handler의 action에 등록할 함수들을 구현하는 스크립트이다.