Ejemplo n.º 1
0
        protected override void Encode(IChannelHandlerContext context, object msg, IByteBuffer output)
        {
            try
            {
                if (msg is RpcMessage rpcMessage)
                {
                    int fullLength = ProtocolConstants.V1_HEAD_LENGTH;
                    int headLength = ProtocolConstants.V1_HEAD_LENGTH;

                    byte messageType = rpcMessage.MessageType;
                    output.WriteBytes(ProtocolConstants.MAGIC_CODE_BYTES);
                    output.WriteByte(ProtocolConstants.VERSION);
                    // full Length(4B) and head length(2B) will fix in the end.
                    output.SetWriterIndex(output.WriterIndex + 6);
                    output.WriteByte(messageType);
                    output.WriteByte(rpcMessage.Codec);
                    output.WriteByte(rpcMessage.Compressor);
                    output.WriteInt(rpcMessage.Id);

                    // direct write head with zero-copy
                    IDictionary <string, string> headMap = rpcMessage.HeadMap;
                    if (headMap?.Count > 0)
                    {
                        int headMapBytesLength = HeadMapSerializer.getInstance().Encode(headMap, output);
                        headLength += headMapBytesLength;
                        fullLength += headMapBytesLength;
                    }

                    byte[] bodyBytes = null;
                    if (messageType != ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST &&
                        messageType != ProtocolConstants.MSGTYPE_HEARTBEAT_RESPONSE)
                    {
                        ISerializer serializer = EnhancedServiceLoader.Load <ISerializer>(((SerializerType)rpcMessage.Codec).ToString());
                        bodyBytes = serializer.Serialize(rpcMessage.Body as AbstractMessage);
                        ICompressor compressor = CompressorFactory.GetCompressor(rpcMessage.Compressor);
                        bodyBytes   = compressor.Compress(bodyBytes);
                        fullLength += bodyBytes.Length;
                    }

                    if (bodyBytes != null)
                    {
                        output.WriteBytes(bodyBytes);
                    }

                    // fix fullLength and headLength
                    int writeIndex = output.WriterIndex;
                    // skip magic code(2B) + version(1B)
                    output.SetWriterIndex(writeIndex - fullLength + 3);
                    output.WriteInt(fullLength);
                    output.WriteShort(headLength);
                    output.SetWriterIndex(writeIndex);
                }
                else
                {
                    throw new NotSupportedException("Not support this class:" + msg.GetType());
                }
            }
            catch (Exception e)
            {
                Logger().LogError(e, "Encode request error!");
            }
        }
Ejemplo n.º 2
0
        public object DecodeFrame(IByteBuffer frame)
        {
            byte b0 = frame.ReadByte();
            byte b1 = frame.ReadByte();

            if (ProtocolConstants.MAGIC_CODE_BYTES[0] != b0 ||
                ProtocolConstants.MAGIC_CODE_BYTES[1] != b1)
            {
                throw new ArgumentException("Unknown magic code: " + b0 + ", " + b1);
            }

            byte version = frame.ReadByte();
            // TODO  check version compatible here

            int   fullLength     = frame.ReadInt();
            short headLength     = frame.ReadShort();
            byte  messageType    = frame.ReadByte();
            byte  codecType      = frame.ReadByte();
            byte  compressorType = frame.ReadByte();
            int   requestId      = frame.ReadInt();

            var rpcMessage = new RpcMessage
            {
                Id          = requestId,
                Codec       = codecType,
                Compressor  = compressorType,
                MessageType = messageType
            };

            // direct read head with zero-copy
            int headMapLength = headLength - ProtocolConstants.V1_HEAD_LENGTH;

            if (headMapLength > 0)
            {
                var map = HeadMapSerializer.getInstance().Decode(frame, headMapLength);
                rpcMessage.HeadMap.PutAll(map);
            }

            // read body
            if (messageType == ProtocolConstants.MSGTYPE_HEARTBEAT_REQUEST)
            {
                rpcMessage.Body = HeartbeatMessage.PING;
            }
            else if (messageType == ProtocolConstants.MSGTYPE_HEARTBEAT_RESPONSE)
            {
                rpcMessage.Body = HeartbeatMessage.PONG;
            }
            else
            {
                int bodyLength = fullLength - headLength;
                if (bodyLength > 0)
                {
                    byte[] bs = new byte[bodyLength];
                    frame.ReadBytes(bs);
                    ICompressor compressor = CompressorFactory.GetCompressor(compressorType);
                    bs = compressor.Decompress(bs);
                    ISerializer serializer = EnhancedServiceLoader.Load <ISerializer>(((SerializerType)rpcMessage.Codec).ToString());
                    rpcMessage.Body = serializer.Deserialize <AbstractMessage>(bs);
                }
            }

            if (Logger().IsEnabled(LogLevel.Debug))
            {
                Logger().LogDebug(rpcMessage.ToString());
            }

            return(rpcMessage);
        }