xsocket分析三,补充说明
xsocket作为一个知名的开源框架(看代码作者好像就一个人。。),有很多地方值得借鉴。
1.内存管理
默认采用了预分配的方式,每个Dispatcher拥有一个MemoryManager对象,MemoryManager管理一大块ByteBuffer默认是16KB,在第一次请求内存时分配。有新的连接时Dispatcher将MemoryManager的引用传给IoSocketHandler,有新的读事件时,IoSocketHandler将数据读在大的ByteBuffer,然后从大的ByteBuffer里分离出读的大小,剩余的部分回收,下次继续使用,如果剩余部分小于最小大小则再分配一个16KB。这里ByteBuffer是由该Dispatcher所管理的所以连接所共享的,由于请求内存、写、回收等操作都是在Dispatcher线程里,所以这里不需要同步。
2.连接管理
主要是对连接最大时长超时、连接空闲时长超时进行管理,由Server的ConnectionManager成员进行管理其维护了一个connection的链表,Server初始化时即实例化connectionManager ,并启动了一个定时任务,定期对链表里的connection进行检查,超时调用connection的函数进行处理。
3.tcp分包
摘自官方手册
As discussed above, data will be segmented on the network level. If the onData() method is called, it is not predictable how many bytes will be received. By calling a read method such as readInt() or readStringByDelimiter() a BufferUnderflowException can occur. To handle this, the read mark support can be used.
即先标记读的起始地方,在读的过程中比如readint不够4byte,则抛出异常重置到标记的地方,ondata方法退出,等有新的数据来时再次调用。
4.多线程,线程池
主要是一个Acceptor线程,一个管理连接的Timer,一个Dispatcher线程池(默认是两个Dispatcher),底层读写操作由Dispatcher完成,每个连接会新建一个ondataevent事件队列和Runnabe对象(注意不是线程),Runnable run方法从队列取事件执行ondataevent也就是我们定义的handler的函数。Runnable对象提交给一个全局的workpool线程池执行,core size为2,max size 为100。
通常情况下就是有六个线程。