public static void ProcessMsg(byte[] bytes, int size)
    {
        if (size < 4)
        {
            Debug.Log($"ROOM - ProcessMsg Error - invalid data size:{size}");
            return;
        }

        byte[] recvHeader = new byte[4];
        Array.Copy(bytes, 0, recvHeader, 0, 4);
        byte[] recvData = new byte[size - 4];
        Array.Copy(bytes, 4, recvData, 0, size - 4);

        int msgId = System.BitConverter.ToInt32(recvHeader, 0);

        switch ((ROOM_REPLY)msgId)
        {
        case ROOM_REPLY.PlayerEnterReply:
            PLAYER_ENTER_REPLY(recvData);
            break;

        case ROOM_REPLY.UploadMapReply:
            UPLOAD_MAP_REPLY(recvData);
            break;

        case ROOM_REPLY.DownloadMapReply:
            DOWNLOAD_MAP_REPLY(recvData);
            break;

        case ROOM_REPLY.EnterRoomReply:
            ENTER_ROOM_REPLY(recvData);
            break;

        case ROOM_REPLY.LeaveRoomReply:
            LEAVE_ROOM_REPLY(recvData);
            break;

        case ROOM_REPLY.DownloadCitiesReply:
            DOWNLOAD_CITIES_REPLY(recvData);
            break;

        case ROOM_REPLY.DownloadActorsReply:
            break;

        case ROOM_REPLY.DownloadResCellReply:
            DOWNLOAD_RESCELL_REPLY(recvData);
            break;

        case ROOM_REPLY.ChangeAiRightsReply:
            CHANGE_AI_RIGHTS_REPLY(recvData);
            break;

        default:
            // 通用消息处理器,别的地方要想响应找个消息,应该调用MsgDispatcher.RegisterMsg()来注册消息处理事件
            MsgDispatcher.ProcessMsg(bytes, size);
            break;
        }
    }
    /// <summary>
    /// 处理服务器接收到的消息
    /// </summary>
    /// <param name="args"></param>
    /// <param name="content"></param>
    public static void ProcessMsg(SocketAsyncEventArgs args, byte[] bytes, int size)
    {
        try
        {
            if (size < 4)
            {
                Debug.Log($"ProcessMsg Error - invalid data size:{size}");
                return;
            }
            _args = args;

            byte[] recvData = new byte[size - 4];
            Array.Copy(bytes, 4, recvData, 0, size - 4);

            // 记录心跳时间,每接收到一条消息,都更新时间,而不仅仅是心跳消息
            HEART_BEAT(null);

            int msgId = ParseMsgId(bytes);
            switch ((ROOM)msgId)
            {
            case ROOM.PlayerEnter:
                PLAYER_ENTER(recvData);
                break;

            case ROOM.HeartBeat:
                HEART_BEAT(recvData);
                break;

            case ROOM.UploadMap:
                UPLOAD_MAP(recvData);
                break;

            case ROOM.DownloadMap:
                DOWNLOAD_MAP(recvData);
                break;

            case ROOM.EnterRoom:
                ENTER_ROOM(recvData);
                break;

            case ROOM.LeaveRoom:
                LEAVE_ROOM(recvData);
                break;

            case ROOM.DownloadCities:
                DOWNLOAD_CITIES(recvData);
                break;

            case ROOM.DownloadActors:
                DOWNLOAD_ACTORS(recvData);
                break;

            case ROOM.DownloadResCell:
                DOWNLOAD_RESCELL(recvData);
                break;

            default:
                // 通用消息处理器,别的地方要想响应找个消息,应该调用MsgDispatcher.RegisterMsg()来注册消息处理事件
                MsgDispatcher.ProcessMsg(args, bytes, size);
                break;
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"Exception - LobbyMsgReply - {e}");
        }
    }