错误的理解
ChannelInboundHandler
、ChannelOutboundHandler
,这里的inbound和outbound是什么意思呢?inbound对应IO输入,outbound对应IO输出?这是我看到这两个名字时的第一反应,但当我看到ChannelOutboundHandler
接口中有read方法时,就开始疑惑了,应该是理解错了,如果outbound对应IO输出,为什么这个接口里会有明显表示IO输入的read方法呢?
正确的理解
直到看到了Stack Overflow上Netty作者Trustin Lee对inbound和outbound的解释,疑团终于解开:
众所周知,Netty是事件驱动的,而事件分为两大类:inboud和outbound,分别由ChannelInboundHandler
和ChannelOutboundHandler
负责处理。所以,inbound和outbound并非指IO的输入和输出,而是指事件类型。
那么什么样的事件属于inbound,什么样的事件属于outbound呢?也就是说,事件类型的划分依据是什么?
答案是:触发事件的源头。
Inbound
由外部触发的事件是inbound事件。外部是指应用程序之外,因此inbound事件就是并非因为应用程序主动请求做了什么而触发的事件,比如某个socket上有数据读取进来了(注意是“读完了”这个事件,而不是“读取”这个操作),再比如某个socket连接了上来并被注册到了某个EventLoop。
Inbound事件的详细列表:
- channelActive / channelInactive
- channelRead
- channelReadComplete
- channelRegistered / channelUnregistered
- channelWritabilityChanged
- exceptionCaught
- userEventTriggered
Outbound
而outbound事件是由应用程序主动请求而触发的事件,可以认为,outbound是指应用程序发起了某个操作。比如向socket写入数据,再比如从socket读取数据(注意是“读取”这个操作请求,而非“读完了”这个事件),这也解释了为什么ChannelOutboundHandler中会有read方法。
Outbound事件列表:
大都是在socket上可以执行的一系列常见操作:绑定地址、建立和关闭连接、IO操作,另外还有Netty定义的一种操作deregister:解除channel与eventloop的绑定关系。
值得注意的是,一旦应用程序发出以上操作请求,ChannelOutboundHandler中对应的方法就会被调用,而不是等到操作完毕之后才被调用,一个handler在处理时甚至可以将请求拦截而不再传递给后续的handler,使得真正的操作并不会被执行。
Inbound events & Outbound operations
以上对inbound和outbound的理解从ChannelPipeline
的Javadoc中也可以得到佐证:
A list of
ChannelHandler
s which handles or intercepts inbound events and outbound operations of aChannel
.ChannelPipeline
implements an advanced form of the Intercepting Filter pattern to give a user full control over how an event is handled and how theChannelHandler
s in a pipeline interact with each other.
重点在于inbound events和outbound operations,即inbound是事件,outbound是操作(直接导致的事件)。
谢谢!大概明白了,但还是有一点小疑问:
“比如向socket写入数据,再比如从socket读取数据(注意是“读取”这个操作请求,而非“读完了”这个事件)”
从socket读取数据不是被动的吗? 这块怎么理解
读数据是主动的, 例如: client端发送数据给Server, 硬件设备接收数据并向buffer中写入, 然后server端主动从buffer中读取数据。
这也是为什么 OutBound中的read(ChannelHandlerContext ctx) 函数没有 msg 参数的原因, 因为只是Server触发了一个读操作, 而不是真的读到数据了。 是我要去做这件事。 (个人理解)
👍
这个写的好,Inbound events & Outbound operations,一句话点通了我,谢谢大佬
当初也是迷迷糊糊,看了这句话才懂的 😀
讲得太好了
一般我们会主动的去发起从socket中读取数据的操作吗?就是发起读数据操作,然后触发Outbound中的read事件。
像进行connect动作都会去Outbound中走一圈吗?如果有代码就好了
不搞java本地没有java开发环境了,自己写个demo测试下吧,打几行日志就看出来了