Netty源码分析系列之writeAndFlush()上

扫描下方二维码或者微信搜索公众号菜鸟飞呀飞,即可关注微信公众号,阅读更多Spring源码分析Java并发编程文章。

微信公众号

前言

前两篇文章中分析了 netty 中解码器相关的源码,解码过程是发生在读数据这一步的,那么读到数据,经过解码器解码后,最终就会交由我们自定义的业务处理中执行,当我们的业务逻辑处理完成后,就需要给客户端响应消息,这就涉及到服务端如何通过 channel 将响应消息写出去的流程了,同时还会涉及到消息的编码过程,因为在 TCP 协议中,数据最终是通过字节流传输的,而我们通常在业务代码中是返回一个对象,因此需要进行编码。接下来本文将会重点分析这两个的过程的源码实现。

Demo 代码

为了方便描述,这里模拟一个简单的场景:netty 服务端在读到客户端发来的消息后,netty 服务端就通过我们自定义的 ChannelHandler 来进行业务处理,并返回一个 Data 对象,Data 类是我们自定义的一个类,然后我们将 Data 对象通过我们自定义的一个编码器 DataEncoder 进行编码,最后将消息发送出去。

netty 服务端启动的 demo 代码

public static void main(String[] args) throws InterruptedException {
   
    NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
    NioEventLoopGroup workerGroup = new NioEventLoopGroup(8);

    ServerBootstrap serverBootstrap = new ServerBootstrap();
    serverBootstrap.channel(NioServerSocketChannel.class)
            .group(bossGroup,workerGroup)
            .childHandler(new ChannelInitializer() {
   
                @Override
                protected void initChannel(Channel ch) throws Exception {
   
                    ChannelPipeline pipeline = ch.pipeline();
                    // 向客户端channel中添加两个channelHandler
                    pipeline.addLast(new DataEncoder());
                    pipeline.addLast(new BusinessHandler());
                }
            });
    serverBootstrap.bind(8080).sync();
}

可以看到,分别向客户端的 channel 的 pipeline 中添加了两个 ChannelHandler:DataEncoder 是自定义的一个编码器,负责进行编码,BusinessHandler 是负责进行业务处理的。因此创建出来的客户端 channel 的 pipeline 的结构如下,这个结构很重要,后面的源码分析全是基于这个结构来分析的。

Demo示例pipeline结构图

DataEncoder 编码器的源码

/**
* 实际上就是一个基于换行符的编码器
*/
public class DataEncoder extends MessageToByteEncoder<Data> {
   

    private static final String LINE = "\r\n";

    @Override
    protected void encode(ChannelHandlerContext ctx, Data msg, ByteBuf out) throws Exception {
   
        if(msg instanceof Data){
   
            out.writeBytes(msg.getMsg().getBytes());
            out.writeLong(msg.getServerTime());
            out.writeBytes(LINE.getBytes());
        }
    }
}

为了简化分析,BusinessHandler 的代码比较简单,它就是直接向客户端返回一个 Data 对象

public class BusinessHandler extends ChannelInboundHandlerAdapter {
   

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
   
      
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值