Пример #1
0
 public void RunCallback()
 {
     MsgCallManager.RunCallback(_protoType, _proto);
 }
Пример #2
0
        /// <summary>
        /// 消息解释
        /// 消息结构:4Byte的消息长度(含前8Byte)+ 4Byte的消息ID + 内容
        /// </summary>
        /// <param name="state">State.</param>
        /// <param name="bytesRead">Bytes read.</param>
        public void ReceiveProtoMsg(MsgStream state, int bytesRead)
        {
            if (isDisposed)
            {
                state.stream = new MemoryStream();
                return;
            }

            if (state.stream.Length > 0)
            {
//                 state.stream = new MemoryStream();
//             }
//             else
//             {
                // There  might be more data, so store the data received so far.
                // 将新接收的数据写入stream尾(消息可能被分包,组好后才能解释)
                state.stream.Position = state.stream.Length;
            }
            state.stream.Write(state.buffer, 0, bytesRead);

            //Utils.LogSys.Log("ReceiveProtoMsg:----------------------->" + state.stream.Length);

            try{
                // Check for end-of-file tag. If it is not there, read
                // more data.
                if (state.stream.Length >= 10)
                {
                    state.stream.Position = 0;
                    uint sumLen = ReadLong(state.stream);

                    long leftLength = state.stream.Length;
                    while (leftLength - 4 >= sumLen) //至少有一个完整的消息时才能解释
                    {
                        float kb_size = (float)sumLen / 1024f;
                        totalMsgSize += (double)kb_size;

                        // All the data has been read from the
                        // client. Display it on the console.
                        uint dlSn = ReadLong(state.stream);
                        if (dlSn == 226)
                        {
                            int test = 1;
                        }
                        if (dlSn == 0 || ServerDlsn == dlSn - 1)
                        {
                            // 正常
                            if (dlSn != 0)
                            {
                                ServerDlsn = dlSn;
                            }

                            int     iProtoType = ReadWord(state.stream);
                            ProtoID protoType  = (ProtoID)iProtoType;
                            //state.stream.Position = state.stream.Position + 8;
                            if (state.stream.Length < sumLen - 6 + state.stream.Position)
                            {
                                Utils.LogSys.LogWarning("Receive Msg Too Less: " + iProtoType);
                                Utils.LogSys.LogWarning("Receive Msg Too Less: count: " + sumLen);
                                Utils.LogSys.LogWarning("Receive Msg Too Less: Position: " + state.stream.Position);
                                Utils.LogSys.LogWarning("Receive Msg Too Less: Length: " + state.stream.Length);
                            }
                            MemoryStream protoStream = new MemoryStream(state.stream.ToArray(),
                                                                        (int)state.stream.Position, (int)sumLen - 6);
                            protoStream.Position = 0;

                            if (!Enum.IsDefined(typeof(ProtoID), iProtoType))
                            {
                                Utils.LogSys.LogWarning("Receive Msg Not Defined: " + iProtoType);
                                MsgCallManager.addMsgObj(protoType, protoStream);
                            }
                            else
                            {
#if UNITY_EDITOR
                                Utils.LogSys.Log("Receive Msg : " + protoType + "(size:" + sumLen + ")");
#endif
                                if (ProtoEncryptList.protoEncryptList.Contains(protoType))
                                {
                                    byte[] bs =
                                        EncryptionUtils.DecryptXor(protoStream, (int)(_encryptKey[0] + dlSn) % 255);
                                    protoStream.Dispose();
                                    protoStream = new MemoryStream(bs, 0, (int)sumLen - 6);
                                }
                                object protoMsg = null;
                                try{
                                    protoMsg = ProtoSerializer.ParseFrom(protoType, protoStream);
                                } catch (Exception e) {
                                    Utils.LogSys.LogError(protoType);
                                    Debug.LogException(e);
                                }
                                if (protoType == ProtoID.SC_LOGIN_REPLY)
                                {
                                    _reconnectKey = (protoMsg as sc_login_reply).reconnect_key;
                                    _encryptKey   = (protoMsg as sc_login_reply).proto_key;
                                }
#if UNITY_EDITOR
                                if (protoType != ProtoID.SC_COMMON_HEARTBEAT_REPLY)
                                {
                                    Utils.LogSys.Log("Got " + protoType + " proto Len:" + sumLen + ". dlSn: " + dlSn);
                                }
#endif
                                protoStream.Seek(0, SeekOrigin.Begin);
                                MsgCallManager.addMsgObj(protoType, protoStream);
                            }
//                            protoStream.Dispose();
                        }
                        else if (ServerDlsn >= dlSn)
                        {
                            // 过期
                            ProtoID protoType = (ProtoID)ReadWord(state.stream);
#if UNITY_EDITOR
                            Utils.LogSys.LogWarning("收到过期包:" + dlSn + "(protoID:" + protoType.ToString() +
                                                    "),不再处理,当前已处理的最新包编号是:" + ServerDlsn);
#endif
                        }
                        else
                        {
                            // 丢包
                            ProtoID protoType = (ProtoID)ReadWord(state.stream);
#if UNITY_EDITOR
                            Utils.LogSys.LogError("丢失包:(编号" + (ServerDlsn + 1) + "--" + (dlSn - 1) +
                                                  ") 这次到达的是protoID:" + protoType + " ,已重新请求");
#endif
                            EventSystem.CallEvent(EventID.SERVER_MSG_MISSING, null);
                        }
                        state.stream.Position = state.stream.Position + sumLen - 6;
                        leftLength            = state.stream.Length - state.stream.Position;
                        if (leftLength > 0)
                        {
                            bool hasHoleMsg = true; //字节流中是否还有完整的消息
                            if (leftLength < 10)
                            {
                                hasHoleMsg = false;
                            }
                            else
                            {
                                sumLen = ReadLong(state.stream);
                                state.stream.Position = state.stream.Position - 4;
                                if (sumLen > leftLength - 4)
                                {
                                    hasHoleMsg = false;
                                }
                            }
                            //1.未解释完,将剩余的字符流存下来
                            if (!hasHoleMsg)
                            {
                                MemoryStream newStream = new MemoryStream();
                                newStream.Write(state.stream.ToArray(), (int)state.stream.Position, (int)leftLength);
                                state.stream.Dispose();
                                state.stream          = newStream;
                                state.stream.Position = 0;
                            }
                            //2.解释完成,继续解释字符流中的下一个消息
                            else
                            {
                                state.stream.Position = state.stream.Position + 4;
                            }
                        }
                        else
                        {
                            //3.解释完成,new一个空字符流下一个消息
                            state.stream.Dispose();
                            state.stream = new MemoryStream();
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                Debug.LogException(e);
            }
        }