一起学Netty(三)之 SimpleChannelInboundHandler

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

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

package com.lyncc.netty.component.simplehandler;

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的源码,其实这是我很不想看见的,尼玛,一个hello world就已经开始看源代码了,还让不让人活了啊,结果源码中显示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来接收,能处理才有鬼,修改一下我们的代码就可以了,重新指定一下处理的类型

package com.lyncc.netty.component.simplehandler;

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方法运行了,也怪我眼瞎,书中写的很清楚:

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

这个是学习Netty走的一段弯路,在这里跟大家share一下~

时间: 2024-07-31 12:06:38

一起学Netty(三)之 SimpleChannelInboundHandler的相关文章

笨鸟学php(三) 运算符与表达式

一.算术运算符    +   -  *  /  %  ++  -- <?php $a = 100; $a++; // $a=$a+1; 先用变量再自增1 ++$a; // $a=$a+1; 先用自增1再用变量 $a--; // $a=$a-1; 先用变量再自减1 --$a; // $a=$a-1; 先用自减1再用变量 echo "a = ".$a."<br>"; // 100 $b = $a % 3.3; // % 会把两边的数转为整数后再进行整除

学习 java netty (三) -- Channel

学习 java netty (三) – Channel 前言:netty封装的channel,看一下官网的定义 A nexus to a network socket or a component which is capable of I/O operations such as read, write, connect, and bind. 可以I/O操作(如读,写,连接和绑定)的连网套接字或组件 A channel provides a user: All I/O operations a

[转帖]脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手

脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手 http://www.52im.net/thread-1729-1-1.html 1.引言 网络编程中TCP协议的三次握手和四次挥手的问题,在面试中是最为常见的知识点之一.很多读者都知道"三次"和"四次",但是如果问深入一点,他们往往都无法作出准确回答. 本篇文章尝试使用动画图片的方式,来对这个知识点进行"脑残式"讲解(哈哈),期望读者们可以更加简单.直观地理解TCP网络通信交互的本

Mina、Netty、Twisted一起学(三):TCP消息固定大小的前缀(Header)

在上一篇博文中,有介绍到用换行符分割消息的方法.但是这种方法有个小问题,如果消息中本身就包含换行符,那将会将这条消息分割成两条,结果就不对了. 本文介绍另外一种消息分割方式,即上一篇博文中讲的第2条:use a fixed length header that indicates the length of the body,用一个固定字节数的Header前缀来指定Body的字节数,以此来分割消息. 上面图中Header固定为4字节,Header中保存的是一个4字节(32位)的整数,例如12即为

一起学Netty(十四)之 Netty生产级的心跳和重连机制

sigh,写这篇博客的时候老脸还是红了一下,心里还是有些唏嘘的,应该算是剽窃吧,每个人的代码功力的确是有差距的,好在文章的标题是"一起学",而不是开涛大神的"跟我学"系列的文章,我们还是多花点时间学习吧,感叹无用~ 最近工作比较忙,但闲暇之余还是看了阿里的冯家春(fengjiachun)的github上的开源代码Jupiter,写的RPC框架让我感叹人外有人,废话不多说,下面的代码全部截取自Jupiter,写了一个比较完整的例子,供大家一起学习分享,再次对@Luca

一起学Netty(九)之LengthFieldBasedFrameDecoder

之前介绍了Netty天然的几种解析器,也稍微介绍了一下ByteToMessageDecoder类,我们对Netty的解码器还是有了一定的了解~ 今天要介绍的是Netty中一个很重要的解码器,因为相比于其他的普通的解码器,这个解码器用的场景更多,并不是说其他解码器不重要,只是因为我们业务场景所致 在当今比较流行的水平拆分的架构之下,RPC协议很是流行,这样可以使各个项目解耦,使得更加灵活,每个项目之间通过远程调用交互,相互之间定义一个通讯私有协议,然后解析,这样就可以进行数据接口交互 例如我们定义

一起学Netty(五)之 初识ByteBuf和ByteBuf的常用API

网络传输的载体是byte,这是任何框架谁也逃脱不了的一种规定,JAVA的NIO提供了ByteBuffer,用来完成这项任务,当然ByteBuffer也很好的完成了这个任务,Netty也提供了一个名字很相似的载体叫做ByteBuf,相比于ByteBuf而言,它有着更加更多友善的API,也更加易于维护,并且它可以扩容 一般来说,ByteBuf都是维护一个byte数组的,它的内部格式是长成这个样子的 * +-------------------+------------------+---------

一起学Netty(六)之 TCP粘包拆包场景

TCP编程底层都有粘包和拆包机制,因为我们在C/S这种传输模型下,以TCP协议传输的时候,在网络中的byte其实就像是河水,TCP就像一个搬运工,将这流水从一端转送到另一端,这时又分两种情况: 1)如果客户端的每次制造的水比较多,也就是我们常说的客户端给的包比较大,TCP这个搬运工就会分多次去搬运. 2)如果客户端每次制造的水比较少的话,TCP可能会等客户端多次生产之后,把所有的水一起再运输到另一端 上述第一种情况,就是需要我们进行粘包,在另一端接收的时候,需要把多次获取的结果粘在一起,变成我们

从零开始学JavaScript三(变量)

一.变量 ECMAscript变量是松散型变量,所谓松散型变量,就是变量名称可以保存任何类型的数据,每个变量仅仅是一个用于保存值的占位符. 定义变量时要使用var操作符 如: var message; /*定义一个名为message的变量,该变量可以用来保存任何值,未初始化的变*量会保存一个特殊的值-undefined */ 二.局部变量 可以声明变量里同时初始化 function test(){ var message='hello'; //定义局部message变量,并初始值为hello a