dubbo源码分析7-编码解码

本文深入分析了Dubbo的编码和解码过程,从NettyClient的doOpen方法入手,讲解了编码和解码入口,重点分析了NettyCodecAdapter的InternalEncoder和InternalDecoder。编码流程涉及DubboCountCodec和DubboCodec,解码流程包括DubboCountCodec.decode()和DecodeableRpcResult.decode()。此外,文章还探讨了Dubbo协议的编码结构,包括request和response的编码细节。
摘要由CSDN通过智能技术生成

本文分享内容如下:

  1. 编码和解码入口分析
  2. 编码流程分析
  3. 编码-dubbo协议分析
  4. 解码流程分析
  5. 解码疑难代码分析

 

编码和解码入口分析

通过netty支持实现

NettyClient

protected void doOpen() throws Throwable {

NettyHelper.setNettyLoggerFactory();

bootstrap = new ClientBootstrap(channelFactory);

// config

// @see org.jboss.netty.channel.socket.SocketChannelConfig

bootstrap.setOption("keepAlive", true);

bootstrap.setOption("tcpNoDelay", true);

bootstrap.setOption("connectTimeoutMillis", getTimeout());

final NettyHandler nettyHandler = new NettyHandler(getUrl(), this);

bootstrap.setPipelineFactory(new ChannelPipelineFactory() {

public ChannelPipeline getPipeline() {

NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyClient.this);

ChannelPipeline pipeline = Channels.pipeline();

pipeline.addLast("decoder", adapter.getDecoder());//line1

pipeline.addLast("encoder", adapter.getEncoder());// line 2

pipeline.addLast("handler", nettyHandler);

return pipeline;

}

});

}

line 1 和 line 2 添加了解码和编码handler。 他们是从 adapter 中获取的

NettyCodecAdapter的两个重要成员

private final ChannelHandler encoder = new InternalEncoder();

private final ChannelHandler decoder = new InternalDecoder();

 

encoder 在编码时被调用

private class InternalEncoder extends OneToOneEncoder {

@Override

protected Object encode(ChannelHandlerContext ctx, Channel ch, Object msg) throws Exception {

com.alibaba.dubbo.remoting.buffer.ChannelBuffer buffer =

com.alibaba.dubbo.remoting.buffer.ChannelBuffers.dynamicBuffer(1024);

NettyChannel channel = NettyChannel.getOrAddChannel(ch, url, handler);

try {

codec.encode(channel, buffer, msg);

} finally {

NettyChannel.removeChannelIfDisconnected(ch);

}

return ChannelBuffers.wrappedBuffer(buffer.toByteBuffer());

}

}

// 依赖codec实现

 

//codec在创建NettyCodecAdapter 被传入

public NettyCodecAdapter(Codec2 codec, URL url, com.alibaba.dubbo.remoting.ChannelHandler handler) {

this.codec = codec;//type is DubboCountCodec

this.url = url;//dubbo://127.0.0.1:20880/tuling.dubbo.server.UserService?application=young-app&codec=dubbo&dubbo=2.6.2&heartbeat=60000&interface=tuling.dubbo.server.UserService&loadbalance=roundrobin&methods=findUser,getUser&pid=181756&qos.enable=false&register.ip=169.254.23.140&side=consumer&timeout=2147483647&timestamp=1575983404587

this.handler = handler;//NettyClient

int b = url.getPositiveParameter(Constants.BUFFER_KEY, Constants.DEFAULT_BUFFER_SIZE);

this.bufferSize = b >= Constants.MIN_BUFFER_SIZE && b <= Constants.MAX_BUFFER_SIZE ? b : Constants.DEFAULT_BUFFER_SIZE;

// bufferSize 默认8M

}

这里的codec 类型是DubboCountCodec,在 NettyClient 初始化时被创建。

代码位于AbstractEndpoint

protected static Codec2 getChannelCodec(URL url) {

String codecName = url.getParameter(Constants.CODEC_KEY, "telnet");

//codecName=“dubbo”

if (ExtensionLoader.getExtensionLoader(Codec2.class).hasExtension(codecName)) {//default enter this

return ExtensionLoader.getExtensionLoader(Codec2.class).getExtension(codecName);// return DubboCountCodec

} else {

return new CodecAdapter(ExtensionLoader.getExtensionLoader(Codec.class)

.getExtension(codecName));

}

}

DubboCountCodec分析

private DubboCodec codec = new DubboCodec();

编码部分只是转发给 DubboCodec 执行

public void encode(Channel channel, ChannelBuffer buffer, Object msg) throws IOException {

codec.encode(channel, buffer, msg);

}

编码部分涉及到 拆包,粘包的处理比较复杂,暂不分析。

 

DubboCodec分析

重写了decod

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值