Netty之ChannelHandlerContext.writeAndFlush与channel.writeAndFlush的区别

本文详细探讨了Netty中ChannelHandlerContext.writeAndFlush()与channel.writeAndFlush()两种方法的事件传播路径差异。前者从当前Handler开始向前传播,直到找到第一个Outbound Handler,而后者则从最后一个Outbound Handler开始,确保对象经过所有必要的处理。通过服务端和客户端的代码示例,阐述了它们在实际应用中的不同应用场景。
摘要由CSDN通过智能技术生成

1、ctx.writeAndFlush()方法的事件传播路径

          ctx.writeAndFlush()方法从Pipeline链中的当前节点开始,往前找到第一个Outbound类型的Handler,把对象往前传播。如果这个对象确认不需要经过其他Outbound类型的Handler处理,那么就使用此方法。

 

 

 

2、ctx.channel().writeAndFlush()方法的事件传播路径

          ctx.channel().writeAndFlush()方法从Pipeline链中的最后一个Outbound类型的Handler开始,把对象往前传播。如果你确认当前创建的对象需要经过后面Outbound类型的Handler,那么就调用此方法。
         在某个Inbound类型的Handler处理完逻辑之后,调用ctx.channel().writeAndFlush()方法,对象会从最后一个Outbound类型的Handler开始,逐个往前传播,路径要比ctx.writeAndFlush()方法长,如下图所示。

3、服务端代码如下

 

package com.example.demo.server;


import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class SInBoundA extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.err.println("Server InBoundA:"+msg);


    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("Server InBoundA channelActive");
        super.channelActive(ctx);



    }

}
package com.example.demo.server;


import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class SInBoundB extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        System.err.println("Server InBoundB:"+msg);

    }


    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.err.println("Server InBoundB channelActive");
        super.channelActive(ctx);
    }


}
package com.example.demo.server;


import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

public class SInBoundC extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
客户端可以通过实现Netty中的ChannelHandler来处理服务端发送的数据。具体来说,你可以实现ChannelInboundHandlerAdapter类,并覆盖channelRead方法来处理服务端发送的数据。在这个方法中,你可以使用ByteBuf类来解码服务端发送的数据。 下面是一个简单的示例代码: ```java public class MyClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf buf = (ByteBuf) msg; String data = buf.toString(CharsetUtil.UTF_8); // 处理接收到的数据 System.out.println("Client received data: " + data); buf.release(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 发生异常时的处理逻辑 cause.printStackTrace(); ctx.close(); } } ``` 在这个示例中,我们通过覆盖channelRead方法来处理服务端发送的数据。当有数据到达时,Netty会自动调用这个方法并将接收到的数据作为参数传入。在这个方法中,我们首先将接收到的数据转换成字符串,然后进行进一步的处理。注意,我们在处理完数据后需要调用ByteBuf的release方法来释放内存。 接下来,你需要将MyClientHandler添加到客户端的ChannelPipeline中,以便在客户端接收到数据时被调用。你可以通过以下代码来实现: ```java Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new MyClientHandler()); } }); ChannelFuture f = b.connect("localhost", port).sync(); ``` 在这个示例中,我们首先创建了一个Bootstrap实例,并指定了事件循环组和通道类型。然后,我们创建了一个ChannelInitializer实例,并在其中添加了MyClientHandler到客户端的ChannelPipeline中。最后,我们通过调用connect方法来连接服务端。当连接成功后,Netty会自动调用MyClientHandlerchannelActive方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

非ban必选

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值