赵计刚
每天进步一点点

服务端响应编码总体流程:

 1 NettyCodecAdapter$InternalEncoder.encode(ChannelHandlerContext ctx, Object msg, ByteBuf out)
 2 -->new NettyBackedChannelBuffer(ByteBuf buffer) // 创建一个buffer
 3 -->NettyChannel.getOrAddChannel(io.netty.channel.Channel ch, URL url, ChannelHandler handler)
 4 -->DubboCountCodec.encode(Channel channel, ChannelBuffer buffer, Object msg)
 5   -->ExchangeCodec.encode(Channel channel, ChannelBuffer buffer, Object msg)
 6       -->encodeResponse(Channel channel, ChannelBuffer buffer, Response res)
 7         -->getSerialization(Channel channel)   //获取Hessian2Serialization序列化实例
 8           -->CodecSupport.getSerialization(URL url)
 9             -->ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(url.getParameter("serialization", "hessian2"))
10         <!-- 构造一个16字节的byte[16] header -->
11         -->byte[] header = new byte[16]
12         -->Bytes.short2bytes(MAGIC, header)  //设置前两个字节为魔数[-38, -69, 0, ..., 0]
13         <!-- 第三个字节:序列化协议ID,如果响应是心跳,添加eventFlag -->
14         -->header[2] = serialization.getContentTypeId();
15          if (res.isHeartbeat()) header[2] |= FLAG_EVENT;
16       <!-- 第四个字节:响应状态 -->
17         -->header[3] = res.getStatus();
18       <!-- 设置第5~12个字节(long是64bit,即8byte):respID == requestID -->
19       -->Bytes.long2bytes(res.getId(), header, 4);
20       <!-- 下面序列化响应体数据 -->
21       -->new Hessian2ObjectOutput(out)
22       -->DubboCodec.encodeResponseData(Channel channel, ObjectOutput out, Object data)
23       -->Bytes.int2bytes(len, header, 12); // 设置第13~16个字节(int是32位,4个字节):消息体长度
24       -->buffer.writeBytes(header); // 将header写入buffer的前16位

与 12.1 客户端请求编码 极其相似。

注意:响应编码中DubboCodec

 1     @Override
 2     protected void encodeResponseData(Channel channel, ObjectOutput out, Object data) throws IOException {
 3         Result result = (Result) data;
 4 
 5         Throwable th = result.getException();
 6         if (th == null) {
 7             Object ret = result.getValue();
 8             if (ret == null) {
 9                 out.writeByte(RESPONSE_NULL_VALUE);
10             } else {
11                 out.writeByte(RESPONSE_VALUE);
12                 out.writeObject(ret);
13             }
14         } else {
15             out.writeByte(RESPONSE_WITH_EXCEPTION);
16             out.writeObject(th);
17         }
18     }

注意:out.writeByte(RESPONSE_VALUE);写入这个响应类型,是为了将来客户端响应解码用的,具体见 12.4 客户端响应解码

请求编码的byte[] header的最终结构:

  • 1~2 byte:魔数
  • 3 byte:requestFlag、序列化方式ID、twowayFlag或eventFlag
  • 5~12 byte :requestID
  • 13~16:请求体长度

响应编码的byte[] header的最终结构:

  • 1~2 byte:魔数
  • 3 byte:序列化方式ID、eventFlag(如果响应信息是心跳信息,添加eventFlag)
  • 4 byte:响应状态,20代表成功
  • 5~12 byte :reponseID(实际上==requestID)
  • 13~16:响应体长度
posted on 2018-01-04 21:07  赵计刚  阅读(407)  评论(0编辑  收藏  举报