哎,各种各样杂七杂八的事情。。。好久没有看代码了,其实要搞明白一个与IO相关的框架,最好的办法就是把它的I/0的读写两个过程搞清楚。。。例如在netty中,如果能将eventLoop的运行原理搞清楚,然后摸清楚整个I/O读写两个过程,那么也就差不太多了。。。。
这次来看看ZeroMQ(java)中如何来处理I/O的,先来看看一个类型的定义,IOObject类型,这个类型应该扮演的是工具类的形象,前面看过在ZeroMQ中所谓的IO线程的定义,那么IOObject就是用于直接与IO线程交互的,或者说的更直接的一点就是它是与IO线程里的poller对象交互的。。。
那么先来看看IOObject的类图吧:
这张图应该将IOObject与IOThread以及Poller之间的关系表现的很清楚了吧。。。。IOObject实现了IPollEvents接口,那么也就代表它可以响应IO事件。。。不过其实它并不直接实现这些IO事件,而是将其委托给内部的一个IPollEvents对象。。只不过是做了一层代理而已。。。
好了,接下来来看看IOObject的代码吧,先来看看它的属性申明:
这个poller就是从IO线程里面获取过来的,handler就是刚刚提到的事件回调的处理对象。。。IOObject不过是对其进行了一层包装而已。。。
那么接下来来看看重要的方法定义:
这个方法用于将当前这个IO对象加入到一个IO线程,其实主要的是要获取这个IO线程的Poller对象。。好了,接下来再来看看如何注册channel以及事件吧:
这部分代码应该很简单吧,而且应该对IOObject的用处比较的清楚了,然后至于说IOObject对象如何响应in_event什么的,前面已经说过了,其实是委托给了handler对象来处理。。。好啦,IOObject的分析就算差不多了。。接下来来看看StreamEngine类型的实现吧,还是先来看看它初略的类图吧:
其实觉得看一个类的类图,基本上就能看出这个类的很多情况,好了,不说闲话了,来看看它的属性的定义吧:
这里面有很多重要的属性,例如handler是SocketChannel类型的,可以知道它才是实际上底层用于通信的,然后又inbuf以及outbuf,这两个东西是干嘛用的应该一眼就看出来了吧,然后还有encoder和decoder,呵呵,可以猜到,读取到的数据先要经过decoder的处理才提交给上层,发送出去的数据也会通过encoder处理成二进制再发送出去。。。然后还有一个io_objcet对象。。。
接下来来看看构造方法吧:
这个比较有意思的就是将channel设置为了非阻塞的模式,然后设置了底层socket的发送以及接受缓冲的大小。。其余的就没啥意思了。。。
这个方法用于将当前IO对象注册到IO线程上面去,并且还要管理session,可以看到这里主要是利用IOObject对象,用于在poller对象上面注册channel,以及读写事件。。。另外还有对握手信息的处理。。。好了,握手这部分的内容,因为现在还没有看,不知道具体的流程是啥样的,就先放一下。。。再来看两个重要的方法定义吧:
这两个方法是用于相应IO事件的,前面提到的IOObject将IO事件其实委托给了内部的handler来处理,其实这个handler对象就是SteamEngine对象,也就是底层的channel有数据可以读写的时候,将会用上面的两个方法来处理。这里就可以看到读写事件最原始的处理流程了,而且也看到了encoder以及decoder的用处。。。这里代码应该还算是比较的简单,由于这部分还涉及到与上层的session对象之间的交互,这个还要等到以后来分析。。。
好了,那么到这里ZeroMQ中IO的处理流程也就算是有了基本的了解了。。。。