数据流是编程范式中的其中一种,何为数据流?
数据流具有无穷数据源、数据流向的特点:
在网络编程中,客户端想要跟服务器进行数据传递,首先就要通过三次握手建立传输通道,绑定好端口,此后通过这个socket进行数据传输。
当通道关闭后,如果想要建立连接,还需再次由客户端发起建立连接的请求,所以后面演进了使用长连接的方式来优化连接频繁地建立和销毁。
在网络编程中,Channel就是干这个事情的。
类似于NIO的Channel,Netty提供了自己的Channel,使得更符合自身框架,叫做ChannelPiple。
JDK的NIO类库种Channel分2种:
客户端的:SockerChannel 服务端的:ServerSocketChannel
Unsafe是一个内部接口,聚合在Channel种协助进行网络读写相关的操作。
Unsafe本身是作为Channel的一个内部辅助类来用的,其实并不应该被Netty框架的上层使用者使用,所以是被命名为Unsafe
是Channel内部的一个内部实现类,是一个接口类型
他不应该被用户代码直接调用,而是由实际负责IO的读写线程来调用。这也是他的名字Unsafe的含义。
作用:将Channel注册到EventLoop的多路复用器上
为了避免多线程并发操作Channel的问题,这里还需要做并发处理
判断当前线程是否是Channel对应的NioEventLoop线程
给Channel绑定对应的Socket
对于服务端,用于绑定监听端口 对于客户端,用于指定客户端Channel的本地绑定Socker地址
把消息添加到唤醒发送数组:ChannelOutboundBuffer里面,并不是真正的写Channel,flush才是把消息写进Channel
io.netty.channel.Channel是Netty网络操作抽象类,里面聚合了JDK的Channel对象
可以Channel理解为操作网络的一个对象,委派角色,他聚合了一组功能,包括但不限于:
JDK 也有NIO原生的Channel,但是Netty是另起炉灶自己抽象出来一个新的Channel,那这里又要讲讲,为什么不用原生JDK的东西了
Netty的Channel设计理念
网络IO操作会触发ChannelPipeline中对应的事件方法
Neety是基于事件驱动,当Channel进行IO操作时,会产生对应的IO事件,然后驱动事件在ChannelPipeline中传播,最后由ChannelHandler对事件进行拦截和处理,不关心的事件可以直接忽略。
采用事件驱动的方式,有很多优点:
网络IO操作直接调用DefaultChannelPipeline的相关方法,由前者中对应的ChannelHandler来进行逻辑处理。
成员变量:
doRegister,把Channel注册到EventLoop中
可以看到第二个参数ops,代表感兴趣的事件,doRegistry的时候直接传了个0,代表对任何事件都不感兴趣
Channel对哪些事件感兴趣呢,比如:
第三个参数是把自己this传过去了,这是为了能让触发事件的时候返回SelectionKey。
根据SelectionKey是可以在多路复用器拿到对应感兴趣的Channel对象,然后去进行处理。
ChannelPipleine和ChannelHandler机制类似于Servlet和Filter过滤器
本质上是责任链模式的实现。
Servlet Filter能够以声明式的方法插入到HTTP请求处理过程中。用于拦截请求和响应,实现对请求的前置处理和后置处理。
Netty的Channel过滤器实现原理跟Servlet Filter机制一致,它将Channel的数据管道抽象成:ChannelPipeline。
数据在ChannelPipeline中流动和传递,ChannelPipeline中持有IO事件拦截器ChannelHandler的链表。
意味着:ChannelHandler可以对IO事件进行拦截和处理
ChannelHandler是可插拔式的,并且我们可以通过新增或者删除ChannelHandler来实现不同业务逻辑,
ChannelPipeline是ChannelHandler的容器
负责ChannelHandler的管理和事件拦截与调度
主要是:负责事件的分发和预处理
一个消息被ChannelPipeline的ChannelHandler链拦截和处理的全过程:
注意:这里为什么是具有顺序性地处理,因为有些ChanelHandler就有顺序性,比如解码那些,需要先将ByteBuf数据解析成对象,然后再将对象二次解码成pojo对象。
Netty中的事件分为:inbound事件和outbound事件,图中左半边对应inboud事件,右半边对应outbound事件。
ChannelInboundHandler处理inboud事件
ChannelOutboundHandler处理outbound事件
误区:区分inboud、outbound并不是简单的IO流,而是触发事件的源头
本篇简单介绍了JDK自带的Channel以及Unsafe其内部的一个实现类。并且从Unsafe的职责来更好的理解它这个名字的含义。
Netty提供的ChannelPipeline内部聚合了一个ChannelHandler链表。ChannelPipeline负责网络IO事件中的调度,而ChannelHandler则是负责拦截,如果是对应感兴趣的事件则处理,否则抛给下一个ChannleHandler。
粗略地讲了一下ChannelHandler为什么要基于责任链的设计模式,做成链表的形式。下一篇文章会着重讲一下ChannelHandler在Netty里面干了些什么事情。
原文链接:https://juejin.cn/post/7213653429416362039
页面更新:2024-06-09
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号