public static void SendMessage(GmRpcNameEnum gmRpcName, byte[] protoData, OnReceiveMsgInvoker handler)
        {
            if (handler != null)
            {
                AddRpcHandler(gmRpcName, handler);
            }

            int totalLength = protoData.Length + 12;
            int rpcNum      = (int)gmRpcName;
            int errorCode   = (int)GmRpcErrorCodeEnum.GmRpcOk;

            byte[] sendByteArray = new byte[totalLength];
            IntEncodingUtil.IntToByteArrayByBigEndian(totalLength).CopyTo(sendByteArray, 0);
            IntEncodingUtil.IntToByteArrayByBigEndian(rpcNum).CopyTo(sendByteArray, 4);
            IntEncodingUtil.IntToByteArrayByBigEndian(errorCode).CopyTo(sendByteArray, 8);
            protoData.CopyTo(sendByteArray, 12);

            ws.Send(sendByteArray);
        }
        public static void InitWebSocket()
        {
            if (ws != null)
            {
                ws.Close();
            }

            ws            = new WebSocket(AppValues.GM_SERVER_URL);
            ws.OnMessage += (sender, e) =>
            {
                if (e.IsBinary)
                {
                    GmResponseMsg msg       = new GmResponseMsg();
                    int           rpcNum    = IntEncodingUtil.ByteArrayToIntByBigEndian(e.RawData, 4);
                    GmRpcNameEnum gmRpcName = (GmRpcNameEnum)rpcNum;
                    msg.RpcName = gmRpcName;
                    int errorCode = IntEncodingUtil.ByteArrayToIntByBigEndian(e.RawData, 8);
                    GmRpcErrorCodeEnum gmRpcErrorCode = (GmRpcErrorCodeEnum)errorCode;
                    msg.ErrorCode = gmRpcErrorCode;
                    if (gmRpcErrorCode == GmRpcErrorCodeEnum.GmRpcOk)
                    {
                        int protoDataLength = e.RawData.Length - 12;
                        msg.ProtoData = new byte[protoDataLength];
                        Buffer.BlockCopy(e.RawData, 12, msg.ProtoData, 0, protoDataLength);
                    }
                    if (rpcHandlerDict.ContainsKey(gmRpcName))
                    {
                        rpcHandlerDict[gmRpcName](msg);
                    }
                }
                else
                {
                    Debug.WriteLine("收到非二进制数据");
                }
            };
            ws.OnOpen += (sender, e) =>
            {
                Debug.WriteLine("连接成功");
                // 开启定时心跳计时器,避免长时间空闲被GM服务器踢下线
                if (heartbeatTimer != null)
                {
                    heartbeatTimer.Close();
                    heartbeatTimer = null;
                }
                if (AppValues.HEARTBEAT_INTERVAL_MSEC > 0)
                {
                    heartbeatTimer           = new Timer(AppValues.HEARTBEAT_INTERVAL_MSEC);
                    heartbeatTimer.Elapsed  += new ElapsedEventHandler(OnHeartbeatTimer);
                    heartbeatTimer.AutoReset = true;
                    heartbeatTimer.Enabled   = true;
                }

                foreach (var hander in connectionOpenHandlerSet)
                {
                    hander(e);
                }
            };
            ws.OnError += (sender, e) =>
            {
                Debug.WriteLine("发生错误:" + e.Message);
                foreach (var hander in connectionErrorHandlerSet)
                {
                    hander(e);
                }
            };
            ws.OnClose += (sender, e) =>
            {
                Debug.WriteLine("连接关闭");
                if (heartbeatTimer != null)
                {
                    heartbeatTimer.Close();
                    heartbeatTimer = null;
                }

                foreach (var hander in connectionCloseHandlerSet)
                {
                    hander(e);
                }
            };

            ws.Connect();
        }