赵计刚
每天进步一点点

客户端响应解码整体流程:

 1 NettyCodecAdapter$InternalDecoder.decode(ChannelHandlerContext ctx, ByteBuf input, List<Object> out)
 2 -->new NettyBackedChannelBuffer(ByteBuf buffer) // 创建一个buffer
 3 -->NettyChannel.getOrAddChannel(io.netty.channel.Channel ch, URL url, ChannelHandler handler)
 4 -->DubboCountCodec.decode(Channel channel, ChannelBuffer buffer)
 5   -->ExchangeCodec.decode(Channel channel, ChannelBuffer buffer)
 6     -->buffer.readBytes(header); //读取header byte[]
 7     -->decode(Channel channel, ChannelBuffer buffer, int readable, byte[] header)
 8       -->检查魔数、检查总长度是否大于等于16
 9       -->获取请求体长度
10       -->new ChannelBufferInputStream(buffer, len)
11       -->DubboCodec.decodeBody(Channel channel, InputStream is, byte[] header)
12         -->CodecSupport.getSerialization(URL url, Byte id) //解析出请求头header[2]中的序列化ID,根据该ID获取与请求编码相同的序列化协议
13         -->Bytes.bytes2long(header, 4) //获取respID
14         <!-- 之后创建一个新的Response对象,将respID及后续解析出来的各种resp属性塞入该对象中 -->
15         -->new DecodeableRpcResult(Channel channel, Response response, InputStream is, Invocation invocation, byte id)
16           -->DecodeableRpcResult.decode()
17             -->decode(Channel channel, InputStream input) //解析请求体参数并将其构造为一个DecodeableRpcResult,最终塞到Request对象的data属性中
18               -->new Hessian2ObjectInput(InputStream is)
19               -->反序列化:in.readObject()

与 12.2 服务端请求解码 极其相似。

不同的地方是:

  1 protected Object decodeBody(Channel channel, InputStream is, byte[] header) throws IOException {
  2         byte flag = header[2], proto = (byte) (flag & SERIALIZATION_MASK);
  3         Serialization s = CodecSupport.getSerialization(channel.getUrl(), proto);
  4         // get request id.
  5         long id = Bytes.bytes2long(header, 4);
  6         if ((flag & FLAG_REQUEST) == 0) {// 解码服务端的响应
  7             // decode response.
  8             Response res = new Response(id);
  9             if ((flag & FLAG_EVENT) != 0) {
 10                 res.setEvent(Response.HEARTBEAT_EVENT);
 11             }
 12             // get status.
 13             byte status = header[3];
 14             res.setStatus(status);
 15             if (status == Response.OK) {
 16                 try {
 17                     Object data;
 18                     if (res.isHeartbeat()) {
 19                         data = decodeHeartbeatData(channel, deserialize(s, channel.getUrl(), is));
 20                     } else if (res.isEvent()) {
 21                         data = decodeEventData(channel, deserialize(s, channel.getUrl(), is));
 22                     } else {
 23                         DecodeableRpcResult result;
 24                         if (channel.getUrl().getParameter(
 25                                 Constants.DECODE_IN_IO_THREAD_KEY,
 26                                 Constants.DEFAULT_DECODE_IN_IO_THREAD)) {
 27                             result = new DecodeableRpcResult(channel, res, is,
 28                                     (Invocation) getRequestData(id), proto);
 29                             result.decode();
 30                         } else {
 31                             result = new DecodeableRpcResult(channel, res,
 32                                     new UnsafeByteArrayInputStream(readMessageData(is)),
 33                                     (Invocation) getRequestData(id), proto);
 34                         }
 35                         data = result;
 36                     }
 37                     res.setResult(data);
 38                 } catch (Throwable t) {
 39                     if (log.isWarnEnabled()) {
 40                         log.warn("Decode response failed: " + t.getMessage(), t);
 41                     }
 42                     res.setStatus(Response.CLIENT_ERROR);
 43                     res.setErrorMessage(StringUtils.toString(t));
 44                 }
 45             } else {
 46                 res.setErrorMessage(deserialize(s, channel.getUrl(), is).readUTF());
 47             }
 48             return res;
 49         } else { // 解码客户端的请求
 50             // decode request.
 51             Request req = new Request(id);
 52             req.setVersion("2.0.0");
 53             req.setTwoWay((flag & FLAG_TWOWAY) != 0);
 54             if ((flag & FLAG_EVENT) != 0) {
 55                 req.setEvent(Request.HEARTBEAT_EVENT);
 56             }
 57             try {
 58                 Object data;
 59                 if (req.isHeartbeat()) {
 60                     data = decodeHeartbeatData(channel, deserialize(s, channel.getUrl(), is));
 61                 } else if (req.isEvent()) {
 62                     data = decodeEventData(channel, deserialize(s, channel.getUrl(), is));
 63                 } else {
 64                     DecodeableRpcInvocation inv;
 65                     if (channel.getUrl().getParameter(
 66                             Constants.DECODE_IN_IO_THREAD_KEY,
 67                             Constants.DEFAULT_DECODE_IN_IO_THREAD)) {
 68                         inv = new DecodeableRpcInvocation(channel, req, is, proto);
 69                         inv.decode();
 70                     } else {
 71                         inv = new DecodeableRpcInvocation(channel, req,
 72                                 new UnsafeByteArrayInputStream(readMessageData(is)), proto);
 73                     }
 74                     data = inv;
 75                 }
 76                 req.setData(data);
 77             } catch (Throwable t) {
 78                 if (log.isWarnEnabled()) {
 79                     log.warn("Decode request failed: " + t.getMessage(), t);
 80                 }
 81                 // bad request
 82                 req.setBroken(true);
 83                 req.setData(t);
 84             }
 85             return req;
 86         }
 87     }
 88 
 89     private ObjectInput deserialize(Serialization serialization, URL url, InputStream is)
 90             throws IOException {
 91         return serialization.deserialize(url, is);
 92     }
 93 
 94     private byte[] readMessageData(InputStream is) throws IOException {
 95         if (is.available() > 0) {
 96             byte[] result = new byte[is.available()];
 97             is.read(result);
 98             return result;
 99         }
100         return new byte[]{};
101     }

DecodeableRpcResult:

 1     public Object decode(Channel channel, InputStream input) throws IOException {
 2         ObjectInput in = CodecSupport.getSerialization(channel.getUrl(), serializationType)
 3                 .deserialize(channel.getUrl(), input);
 4 
 5         byte flag = in.readByte();
 6         switch (flag) {
 7             case DubboCodec.RESPONSE_NULL_VALUE:
 8                 break;
 9             case DubboCodec.RESPONSE_VALUE://这个值是响应编码是编码进来的,用来表示响应的返回类型
10                 try {
11                     Type[] returnType = RpcUtils.getReturnTypes(invocation);
12                     setValue(returnType == null || returnType.length == 0 ? in.readObject() :
13                             (returnType.length == 1 ? in.readObject((Class<?>) returnType[0])
14                                     : in.readObject((Class<?>) returnType[0], returnType[1])));
15                 } catch (ClassNotFoundException e) {
16                     throw new IOException(StringUtils.toString("Read response data failed.", e));
17                 }
18                 break;
19             case DubboCodec.RESPONSE_WITH_EXCEPTION:
20                 try {
21                     Object obj = in.readObject();
22                     if (obj instanceof Throwable == false)
23                         throw new IOException("Response data error, expect Throwable, but get " + obj);
24                     setException((Throwable) obj);
25                 } catch (ClassNotFoundException e) {
26                     throw new IOException(StringUtils.toString("Read response data failed.", e));
27                 }
28                 break;
29             default:
30                 throw new IOException("Unknown result flag, expect '0' '1' '2', get " + flag);
31         }
32         return this;
33     }

setValue:设置DecodeableRpcResult的Object result属性。

响应解码结束。

posted on 2018-01-04 21:28  赵计刚  阅读(1314)  评论(0编辑  收藏  举报