예제 #1
0
        /// <summary>
        /// 序列化并发送消息,如果序列化异常标记消息为错误状态仍旧发送,接收端根据消息类型是请求还是响应作不同处理
        /// </summary>
        public void SendMessage <T>(ref T msg) where T : struct, IMessage
        {
            //Log.Debug($"[{System.Diagnostics.Process.GetCurrentProcess().ProcessName}]发送:{msg.Type}");
            MessageFlag flag     = MessageFlag.None;
            int         msgId    = Interlocked.Increment(ref sendMsgIdIndex);
            ulong       sourceId = 0; //TODO: fix

            var mws = MessageWriteStream.ThreadInstance;

            mws.Reset(msg.Type, msgId, sourceId, flag, _sendQueue);
            BinSerializer bs = BinSerializer.ThreadInstance;

            bs.Init(mws);
            try
            {
                bs.Write((byte)msg.PayloadType); //不用bs.Serialize(msg)防止box
                msg.WriteObject(bs);
                mws.FinishWrite();
            }
            catch (Exception ex)
            {
                //发生异常,则通知接收端取消挂起的消息
                unsafe
                {
                    SendCancelMessage(mws.CurrentChunk);
                }
                //重新抛出异常
                Log.Warn(ExceptionHelper.GetExceptionDetailInfo(ex));
                throw new MessageSerializationException(MessageSerilizationErrorCode.SerializeFail, ex);
            }
            finally
            {
                bs.Clear();
            }
        }
예제 #2
0
        /// <summary>
        /// 反序列化消息 注意:不管是否成功归还缓存块至通道
        /// </summary>
        /// <exception>只抛出MessageSerializationException</exception>
        public unsafe T Deserialize <T>(MessageChunk *first) where T : struct, IMessage
        {
            if (first == null)
            {
                throw new MessageSerializationException(MessageSerilizationErrorCode.DeserializeFailByFirstSegmentIsNull, null);
            }
            //??注意:不能判断first->First == first, 因为AppContainer子进程内收到的路由消息已修改第一包

            var mrs = MessageReadStream.ThreadInstance;

            mrs.Reset(first);
            BinSerializer bs = BinSerializer.ThreadInstance;

            bs.Init(mrs);
            T res = default;

            try
            {
                var payloadType = bs.ReadByte(); //不用res = bs.Deserialize();避免box
                if (payloadType != (byte)res.PayloadType)
                {
                    throw new MessageSerializationException(MessageSerilizationErrorCode.DeserializeFailByMessageType, null);
                }

                res.ReadObject(bs);
                mrs.Close();
            }
            catch (MessageSerializationException)
            {
                throw;
            }
            catch (Exception ex) //TODO:单独捕获解密错误信息
            {
                //Log.Warn(ex.StackTrace);
                throw new MessageSerializationException(MessageSerilizationErrorCode.DeserializeFail, ex);
            }
            finally
            {
                ReturnMessageChunks(first);
                bs.Clear();
            }

            return(res);
        }