一起学netty(12)ChannelInboundHandler和ChannelOutboundHandler处理器
ChannelInboundHandler
ChannelInboundHandler是入栈消息处理的核心接口,如下:
public interface ChannelInboundHandler extends ChannelHandler {
void channelRegistered(ChannelHandlerContext var1) throws Exception;
void channelUnregistered(ChannelHandlerContext var1) throws Exception;
void channelActive(ChannelHandlerContext var1) throws Exception;
void channelInactive(ChannelHandlerContext var1) throws Exception;
void channelRead(ChannelHandlerContext var1, Object var2) throws Exception;
void channelReadComplete(ChannelHandlerContext var1) throws Exception;
void userEventTriggered(ChannelHandlerContext var1, Object var2) throws Exception;
void channelWritabilityChanged(ChannelHandlerContext var1) throws Exception;
void exceptionCaught(ChannelHandlerContext var1, Throwable var2) throws Exception;
}
其主要方法描述如下:
- channelRegistered: 当一个Channel注册到EventLoop上,可以处理I/O时被调用
- channelUnregistered: 当一个Channel从它的EventLoop上解除注册,不再处理I/O时被调用
- channelActive: 当Channel变成活跃状态时被调用;Channel是连接/绑定、就绪的
- channelInactive: 当Channel离开活跃状态,不再连接到某个远端时被调用
- channelReadComplete: 当Channel上的某个读操作完成时被调用
- channelRead: 当从Channel中读数据时被调用
- channelWritabilityChanged: 当Channel的可写状态改变时被调用。通过这个方法,用户可以确保写操作不会进行地太快(避免OutOfMemoryError)或者当Channel又变成可写时继续写操作。Channel类的isWritable()方法可以用来检查Channel的可写状态。可写性的阈值可以通过Channel.config().setWriteHighWaterMark()和Channel.config().setWriteLowWaterMark()来设定。
- userEventTriggered: 因某个POJO穿过ChannelPipeline引发ChannelnboundHandler.fireUserEventTriggered()时被调用。
一般我们在自定义消息处理器的时候通常会实现ChannelInboundHandler的一个子类ChannelInboundHandlerAdapter,它默认实现了调用下一个处理器的方法。
//入栈消息处理器
pipeline.addLast(new ChannelInboundHandlerAdapter(){
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println(msg.getClass());
//释放内存
ReferenceCountUtil.release(msg);
}
});
可以看到,当消息处理器继承ChannelInboundHandlerAdapter类时并且msg的类型是ByteBuf类型时,需要执行ReferenceCountUtil.release(msg);方法手动释放ByteBuf的内存,因为ByteBuf使用的是直接内存。
为了避免上述情况的发生,我们还可以继承SimpleChannelInboundHandler类,如下:
//入栈消息处理器
pipeline.addLast(new SimpleChannelInboundHandler<ByteBuf>(){
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf msg) throws Exception {
System.out.println(msg);
}
});
它实际上是ChannelInboundHandlerAdapter的子类,它在实现channelRead方法时对ByteBuf进行了处理。
ChannelOutboundHandler
ChannelOutboundHandler是出栈消息处理的核心接口,一般在做回写数据的消息编码时会用到。它的子类一般都是各种编码器,如StringEncoder,MessageToMessageEncoder,ProtobufEncoder,HttpRequestEncoder等。
public interface ChannelOutboundHandler extends ChannelHandler {
void bind(ChannelHandlerContext var1, SocketAddress var2, ChannelPromise var3) throws Exception;
void connect(ChannelHandlerContext var1, SocketAddress var2, SocketAddress var3, ChannelPromise var4) throws Exception;
void disconnect(ChannelHandlerContext var1, ChannelPromise var2) throws Exception;
void close(ChannelHandlerContext var1, ChannelPromise var2) throws Exception;
void deregister(ChannelHandlerContext var1, ChannelPromise var2) throws Exception;
void read(ChannelHandlerContext var1) throws Exception;
void write(ChannelHandlerContext var1, Object var2, ChannelPromise var3) throws Exception;
void flush(ChannelHandlerContext var1) throws Exception;
}
猜你喜欢
official
1452
之前的文章中提到过,单线程的nio模型任然有一定缺点。在上一节《一起学netty(7)netty的线程模型》中也提到,netty的出现,封装了nio复杂的代码,并且介入多线程来处理事件,最大限度的提
official
1480
编码器和解码器在网络应用中需要实现某种编解码器,将原始字节数据与自定义的消息对象进行互相转换。网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码
official
1931
上一篇《一起学netty(2)nio模型及多路复用器》中已经简单介绍了nio模型,以及多路复用器的概念,并了解nio是非阻塞的网络模型,以及与bio的区别。本篇将继续深入理解nio,以及select
official
1434
是一个Pipeline。入栈处理器通常是ChannelInboundHandlerAdapter的子类,主要用于读取和处理客户端的数据。(包括数据包解码,业务逻辑处理等)出栈处理器通常是ChannelO
official
1157
Websocket协议和http协议的关系websocket是基于TCP的一个应用协议,与HTTP协议的关联之处在于websocket的握手数据被HTTP服务器当作HTTP包来处理,主要通过
official
1204
什么是心跳?顾名思义,所谓心跳,即在TCP长连接中,客户端和服务器之间定期发送的一种特殊的数据包,通知对方自己还在线,以确保TCP连接的有效性。为什么需要心跳?因为网络的不可靠性,有可能在TCP保持
official
1145
。ServiceSocketChannel本身不具备数据传输的能力,它只能监听新进来的TCP链接通道。当有新的TCP链接通道建立后,它会创建一个SocketChannel的对象,代表和客户端的唯一连接通道
official
1285
在上一节《一起学netty(6)》的文章中,简要说明了用nio原生代码写程序的一些不足和问题,以及netty在nio的基础上大致做了那些工作。其中提到一点就是当活跃客户端的数量太多,单线程处理时所带
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。