博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mina源码分析
阅读量:6622 次
发布时间:2019-06-25

本文共 2302 字,大约阅读时间需要 7 分钟。

 
Server端代码调用逻辑
NioSocketAcceptor 中有一Selector对象,服务端ServerSocketChannel会注册到此selecter上,接收所有的客户端连接请求。
 
AbstractPollingIoAcceptor 的IoProcessor<S> processor是SimpleIoProcessorPool实例,默认是创建cpu核+1个NioProcessor,NioSocketSession里的processor也是该实例的引用。
 

NioSocketAcceptor ->AbstractIoAcceptor.bind->AbstractPollingIoAcceptor.bindInternal->startupAcceptor

在此方法中创建一个Acceptor(Acceptor是一内部类),启动线程,接收所有的客户端连接。
 
Acceptor调用AbstractPollingIoAcceptor的processHandles,该方法的 session.getProcessor().add(session)是调用了SimpleIoProcessorPool的add方法,该方法会根据session的id取模选择一个NioProcessor进行读写操作的处理(以此保证同一客户端到来的请求被同一个Processor处理)。
 
AbstractPollingIoProcessor的add方法里会启动Processor线程,处理io读写操作。
 
Processor调用AbstractPollingIoProcessor的handleNewSessions处理从NioSocketAcceptor传过来的NioSession(存放到了newSessions中),
handleNewSessions ->addNow>init中向NioProcessor的selecter注册读操作,并在这里重设了NioSession的selectionKey.
 
 
NioSession在 NioSocketAcceptor处理客户端连接请求时被创建,传递到NioProcessor中,在处理读取操作之前修改了selectionKey属性,注册读写连接事件时
ch.register(selector, SelectionKey.OP_READ, session)一直被当做attach存在于整个长连接生命周期。
 
 
NioSession的WriteRequestQueue writeRequestQueue;用来存储同一个客户端过来且已读完数据的session(如果业务逻辑使用了ExecutorFilter,默认是使用的OrderedThreadPoolExecutor),以此来保证先到的请求先得到相应读操作按数据到来顺序处理
 
 
Processor调用AbstractPollingIoProcessor的 process(),处理已准备好的读操作(同时把已经准备好写的session放入flushingSessions中),在read(sessioin)方法中会触发IoFilterChain中的所有filter的 messgeReceived事件,处理完最后一个filter,则会调用IoHander处理业务逻辑, hander里会调用session.write发送消息,但该方法不会写数据,只是调用IoFilterChain的fireFilterWrite方法,从TailFilter到HeadFilter触发filterWrite方法,在HeadFilter里 s.getProcessor().write(s, writeRequest)给session添加writeRequest,真正的写操作在 flush(currentTime)方法里进行。
flush->flushNow(writeBuffer写成数据)->fireMessageSent 会触发filterChain的messageSend事件
 
nio粘包断包解决方案
ProtocolCodecFilter 的messageReceived方法进行解码,filterWrite进行编码;messageReceived方法里定义的ProtocolDecoderOutput decoderOut对象会存储ProtocolDecoder解析的数据,解码完成后且decoderOut的messageQueue(queue里可存储多个请求的数据)非空才会调用decoderOut.flush(nextFilter, session)触发后续的filter;NioSession可以用setAttribute存储客户端请求的数据信息;如果CumulativeProtocolDecoder子类的doDecode方法能够解析一个请求过来的数据, 则调用decoderOut.write()存储此请求数据;doDecode返回false,标识此读事件处理完成或数据不足,数据不足则会调用session.setAttribute(BUFFER, buf)存储这次读事件得到的数据,等下次读事件到来后与此数据合并,再进行解码;返回true,说明此读事件可能包含多个请求,需继续调用子类的doDecode方法。当buf中数据读取完毕后会删除session中存储的buf。
 
nio channel同一时刻只能有一个读或者写操作

 

转载于:https://www.cnblogs.com/burgeen/p/3618004.html

你可能感兴趣的文章
get app id
查看>>
poj 3624 0/1背包暨0/1背包的学习
查看>>
[俗一下]世界500强公司的面试问题与答案提示 [转]
查看>>
使用 Excel Services ,结合 Analysis Services 在 SharePoint 中发布报表
查看>>
SQL Server数据导入导出技术概述与比较
查看>>
format的用法
查看>>
DHCPv6 server port and DHCPv6 client port
查看>>
10个最佳的触控手式的JavaScript框架(转)
查看>>
BitmapFactory.Options避免 内存溢出 OutOfMemoryError的优化方法
查看>>
Python中通过Image的open之后,去show结果打不开bmp图片,无法正常显示图片
查看>>
DNGuard 免费的DotNet加密保护工具 V1.0
查看>>
编程中的命名设计
查看>>
easyui form validate总是返回false原因
查看>>
在(CListView)列表视图中添加右键菜单的方法
查看>>
推荐《HeadFirst设计模式》
查看>>
自定义服务器控件(处理不同的浏览器)
查看>>
解决IE6-IE7下li上下间距
查看>>
配置级别greenplum 可用空间计算
查看>>
聚集索引更新后会不会马上重新排序
查看>>
幸运大抽奖
查看>>