Exemplo n.º 1
0
        /// <summary>
        /// Initialize net component and connect to remote server.
        /// </summary>
        /// <param name="remoteAddress">The address of remote server to connect.</param>
        /// <param name="remotePort">The port of remote server to connect.</param>
        public Boolean Initialize(String remoteAddress, Int32 remotePort)
        {
            // 客户端处理IPV6的时候逻辑,需要用到
#if UNITY_5_3_OR_NEWER
            if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
                String        newServerIp      = "";
                AddressFamily newAddressFamily = AddressFamily.InterNetwork;
                getIPType(remoteAddress, remotePort.ToString(), out newServerIp, out newAddressFamily);
                if (!string.IsNullOrEmpty(newServerIp))
                {
                    remoteAddress = newServerIp;
                }
            }
#endif

            // analyze the ip address and port info
            IPAddress myIp;
            if (IPAddress.TryParse(remoteAddress, out myIp))
            {
                //strMsg = String.Format("BuildPeer TryParse {0} success", remoteAddress);
                //Debug.WriteLine(strMsg);

                m_ipEndPoint = new IPEndPoint(myIp, remotePort);
            }
            else
            {
                //strMsg = String.Format("BuildPeer GetHostEntry {0} fail", remoteAddress);
                //Debug.WriteLine(strMsg);
                return(false);
            }

            // Do some cleanup if necessery
            if (State != ConnectionState.None)
            {
                Close();
            }

            // Clean all messages of last connection
            RecvQueue.Clear();

            // Clean all event args of last connection
            m_connEventArg    = new SocketAsyncEventArgs();
            m_receiveEventArg = new SocketAsyncEventArgs();

            // init event args
            m_connEventArg.Completed     += new EventHandler <SocketAsyncEventArgs>(OnCompletedForConnect);
            m_connEventArg.RemoteEndPoint = m_ipEndPoint;
            m_receiveEventArg.Completed  += new EventHandler <SocketAsyncEventArgs>(OnCompletedForReceive);
            m_receiveEventArg.SetBuffer(new byte[ProtoConst.MAX_PACKAGE_LENGTH], 0, ProtoConst.MAX_PACKAGE_LENGTH);

            // Change state
            State = ConnectionState.Connecting;

            // Create work resource
            RecvCache = new MessageBlock((int)ConnectionConst.CACHE_MAX_BYTE);
            try
            {
                StartConnectionWork();
            }catch (Exception e)
            {
                Log.Error(e);
                return(true);
            }
            return(true);
        }
        /// <summary>
        /// Decodes the message.
        /// </summary>
        /// <returns>The message.</returns>
        /// <param name="dataBlock">Data block.</param>
        /// <param name="dataOffset">Data offset.</param>
        /// <param name="dataLen">Data length.</param>
        /// <param name="newMsg">New message.</param>
        /// <returns>
        ///     != null     : A protocol message
        ///     == null     : No full message exist
        ///     Exception   : ProtoException to indicate HACK stream
        /// </returns>
        public static Object DecodeMessage(MessageBlock rCache, out ushort msgId, out bool isRpc)
        {
            msgId = 0;
            isRpc = false;
            // get the message head's length
            int headLength = sizeof(ushort) * 2;

            // Not enough data for header
            if (rCache.Length < headLength)
            {
                //Debug.WriteLine(String.Format("DecodeMessage Not enough data for header. rCache.Length={0} < headLength={1}", rCache.Length, headLength));
                return(null);
            }

            // get message length
            ushort pakFullLength = rCache.ReadUInt16();

            // Bad stream
            if (pakFullLength < headLength)
            {
                throw new ProtoException(string.Format("Hack stream, TotalLength={0}", pakFullLength));
            }

            int pakBodyLength = pakFullLength - headLength;

            //Debug.WriteLine(String.Format("DecodeMessage Before rCache.Length={0} pakBodyLength={1} ", rCache.Length, pakBodyLength));

            // Not enough data for body
            // 注意这里需要考虑后面一个包头的长度
            if (rCache.Length < pakBodyLength + sizeof(ushort))
            {
                // Move read ptr to back
                // 此处只处理了UInt16长度的数据,所以回滚需要一致,不能使用headLength
                rCache.ReadPtr(-(sizeof(ushort)));
                //Debug.WriteLine(String.Format("DecodeMessage Not enough data for body rCache.Length={0} < pakBodyLength={1}", rCache.Length, pakBodyLength));
                return(null);
            }

            // get message id field
            ushort pakMessageIdField = rCache.ReadUInt16();

            // get compressed tag
            isRpc = pakMessageIdField >> (sizeof(ushort) * 8 - 1) == 1;
            // get the protocol id
            msgId = (ushort)(pakMessageIdField & 0x7FFF);

            // deserialize message, we should decompress message body data if needed
            Type pakType = OpcodeTypeDictionary.Instance.GetTypeById(msgId);
            // Use ProtoBuf to deserialize message
            //object ccMsg =  MessageFactory.CreateMessage(pakType);//2019.7.17改为对象池
            object ccMsg = Activator.CreateInstance(pakType);

            //Debug.WriteLine(String.Format("DecodeMessage msgId={0} pakBodyLength={1} isCompressed={2} pakType={3}", msgId, pakBodyLength, isCompressed, pakType.ToString()));
            try
            {
                using (MemoryStream readStream = rCache.GetStream(pakBodyLength))
                {
                    //将消息序列化,根据所提供的序列化器进行序列化和反序列化
                    ProtobufPraserHelper.s_protobufPacker.DeserializeFrom(ccMsg, readStream);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("msgId={0}, isRpc={1} pakBodyLength={2}",
                                                  msgId, isRpc, pakBodyLength), ex);
            }

            //Debug.WriteLine(String.Format("DecodeMessage rCacheInfo Length={0} WrPtr={1} RdPtr={2}", rCache.Length, rCache.WrPtr, rCache.RdPtr));
            return(ccMsg);
        }