UnityServer - 패킷 생성기 (4)

k_hyun·2022년 11월 9일
0

Unity_Server

목록 보기
30/32

ClientSession.cs

public override void OnRecvPacket(ArraySegment<byte> buffer)
        {
            PacketManager.Instance.OnRecvPacket(this, buffer);            
        }

PacketManager.cs

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에 작성되어 있다.

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에 등록할 함수들을 구현하는 스크립트이다.

0개의 댓글