天天看点

Netty之SimpleChannelInboundHandler

源码地址: GitHub

SimpleChannelInboundHandler这个类,在《Netty in Action》该书中的原版的Hello world的demo的客户端就是使用的SimpleChannelInboundHandler来作为处理器的,我本来也是使用这个类作为我处理类的,但是做一个新手,这个类还是让我走了一点弯路,我们可以看到SimpleChannelInboundHandler中有一个channelRead0的方法需要我们实现:

Netty之SimpleChannelInboundHandler

记得当时就是使用的channelRead0这个方法,结果服务器端就是不打印,服务器返回的结果,当时客户端是这样写的

import io.netty.buffer.ByteBuf;  
import io.netty.channel.ChannelHandlerContext;  
import io.netty.channel.SimpleChannelInboundHandler;  
  
public class BaseClientHandler extends SimpleChannelInboundHandler<ByteBuf>{  
      
    @Override  
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {  
        System.out.println("Client channelRead0 received:" + msg);  
    }  
      
//    @Override  
//    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {  
//        System.out.println("Client channelRead received:" + msg);  
//          
//    }  
    
     @Override  
     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {  
         cause.printStackTrace();  
         ctx.close();  
     }  
  
}  
           

结果channelRead0方法就是不运行执行,让我郁闷了有一会,后来,我打开了SimpleChannelInboundHandler的源码,,结果源码中显示SimpleChannelInboundHandler是继承于ChannelInboundHandlerAdapter,重写了channelRead方法:

@Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        boolean release = true;
        try {
            if (acceptInboundMessage(msg)) {
                @SuppressWarnings("unchecked")
                I imsg = (I) msg;
                channelRead0(ctx, imsg);
            } else {
                release = false;
                ctx.fireChannelRead(msg);
            }
        } finally {
            if (autoRelease && release) {
                ReferenceCountUtil.release(msg);
            }
        }
    }
           

原来我们SimpleChannelInboundHandler后面指定了处理类型,也就是源码中的"I",acceptInboundMessage方法判断msg是不是SimpleChannelInboundHandler中指定的类型,我们这边指定的是ByteBuf,感觉没啥问题啊,但是我们忽略了一个问题,我们客户端中有3个处理器,两个inbound类型的处理器,其中一个就是HelloWorldClientHandler,还有一个就是StringDecoder,此时我内心是崩溃的,上一个处理器已经把服务器端的信息转化成String,我还用ByteBuf来接收,能处理才有鬼,修改一下我们的代码就可以了,重新指定一下处理的类型

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;

public class BaseClientHandler extends SimpleChannelInboundHandler<String>{
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        System.out.println("Client channelRead0 received:" + msg);
    }
    
//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//        System.out.println("Client channelRead received:" + msg);
//        
//    }
  
     @Override
     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
         cause.printStackTrace();
         ctx.close();
     }
}
           

这样就能使channelRead0方法运行了,也怪我眼瞎,书中写的很清楚:

Netty之SimpleChannelInboundHandler

SimpleChannelInboundHandler的channelRead0还有一个好处就是你不用关心释放资源,因为源码中已经帮你释放了,所以如果你保存获取的信息的引用,是无效的~

版权声明:本文为CSDN博主「weixin_34032792」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_34032792/article/details/91932114