您的位置:首页 > 其它

12.3 服务端响应编码

2018-01-04 21:07 134 查看
服务端响应编码总体流程:

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:响应体长度
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: