sessionCreate(IoSession)
? IoSession对象被创建时的回调,一般用于进行会话初始化操作。注意:与sessionOpened(IoSession)不同,IoSession对象的创建并不意味着对应底层TCP连接的建立,而仅仅代表字面意思:一个IoSession对象被创建出来了。
sessionOpened(IoSession)
? IoSession对象被打开时回调。在TCP中,该事件是在TCP连接建立时触发,一般可用于发起连接建立的握手、认证等操作。
sessionIdle(IoSession,IdleStatus)
? IoSession对象超时时回调。当一个IoSession对象在指定的超时时常内没有读写事件发生,就会触发该事件,一般可用于通知服务器断开长时间闲置的连接等处理。具体的超时设置可由 IoService.setWriteIdleTime(int) ,IoService.setReadIdleTime(int) ,IoService.setBothIdleTime(int)设置。
messageReceived(IoSession,Object)
? 当接收到IoSession对Client发送的数据时回调。
messageSent(IoSession,Object)
? 当发送给IoSession对Client的数据发送成功时回调。
exceptionCaught(IoSession,Throwable)
? 当会话过程中出现异常时回调,通常用于错误处理。
?
?
?
session.write(Object)方法是一个异步方法,对该方法的调用并不会阻塞,而是向Mina投递一个异步的写操作,并返回一个可用于对已投递异步写操作进行控制的WriteFuture对象。例如:调用WriteFuture的await()或awaitUninterruptibly(),可由同步等待该异步操作的完成。
?
在I/O处理器中实现业务逻辑的时候,对于简单的情况,一般只需要在messageReceived中对传入的消息进行处理。如果需要写回数据到对等体,用IoSession.write()即可。
另外的情况,client和server的通信协议比较复杂,client是有状态变迁的,这时可用Mina提供的状态机实现,可使用IO处理器的实现更加简单。
?
androidpn中XmppIoHandler源代码:
- package?org.androidpn.server.xmpp.net;??
- ??
- import?java.util.Map;??
- import?java.util.concurrent.ConcurrentHashMap;??
- ??
- import?org.androidpn.server.xmpp.XmppServer;??
- import?org.apache.commons.logging.Log;??
- import?org.apache.commons.logging.LogFactory;??
- import?org.apache.mina.core.service.IoHandler;??
- import?org.apache.mina.core.session.IdleStatus;??
- import?org.apache.mina.core.session.IoSession;??
- import?org.dom4j.io.XMPPPacketReader;??
- import?org.jivesoftware.openfire.net.MXParser;??
- import?org.jivesoftware.openfire.nio.XMLLightweightParser;??
- import?org.xmlpull.v1.XmlPullParserException;??
- import?org.xmlpull.v1.XmlPullParserFactory;??
- ??
- /**??
- ?*?This?class?is?to?create?new?sessions,?destroy?sessions?and?deliver?
- ?*?received?XML?stanzas?to?the?StanzaHandler.?
- ?*?
- [email protected]([email protected])?
- ?*/??
- public?class?XmppIoHandler?implements?IoHandler?{??
- ??
- ????private?static?final?Log?log?=?LogFactory.getLog(XmppIoHandler.class);??
- ??
- ????public?static?final?String?XML_PARSER?=?"XML_PARSER";??
- ??
- ????private?static?final?String?CONNECTION?=?"CONNECTION";??
- ??
- ????private?static?final?String?STANZA_HANDLER?=?"STANZA_HANDLER";??
- ??
- ????private?String?serverName;??
- ??
- ????private?static?Map<Integer,?XMPPPacketReader>?parsers?=?new?ConcurrentHashMap<Integer,?XMPPPacketReader>();??
- ??
- ????private?static?XmlPullParserFactory?factory?=?null;??
- ??
- ????static?{??
- ????????try?{??
- ????????????factory?=?XmlPullParserFactory.newInstance(??
- ????????????????????MXParser.class.getName(),?null);??
- ????????????factory.setNamespaceAware(true);??
- ????????}?catch?(XmlPullParserException?e)?{??
- ????????????log.error("Error?creating?a?parser?factory",?e);??
- ????????}??
- ????}??
- ??
- ????/**?
- ?????*?Constructor.?Set?the?server?name?from?server?instance.??
- ?????*/??
- ????protected?XmppIoHandler()?{??
- ????????serverName?=?XmppServer.getInstance().getServerName();??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?from?an?I/O?processor?thread?when?a?new?connection?has?been?created.?
- ?????*/??
- ????public?void?sessionCreated(IoSession?session)?throws?Exception?{??
- ????????log.debug("sessionCreated()...");??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?when?a?connection?has?been?opened.?
- ?????*/??
- ????public?void?sessionOpened(IoSession?session)?throws?Exception?{??
- ????????log.debug("sessionOpened()...");??
- ????????log.debug("remoteAddress="?+?session.getRemoteAddress());??
- ????????//?Create?a?new?XML?parser??
- ????????XMLLightweightParser?parser?=?new?XMLLightweightParser("UTF-8");??
- ????????session.setAttribute(XML_PARSER,?parser);??
- ????????//?Create?a?new?connection??
- ????????Connection?connection?=?new?Connection(session);??
- ????????session.setAttribute(CONNECTION,?connection);??
- ????????session.setAttribute(STANZA_HANDLER,?new?StanzaHandler(serverName,??
- ????????????????connection));??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?when?a?connection?is?closed.?
- ?????*/??
- ????public?void?sessionClosed(IoSession?session)?throws?Exception?{??
- ????????log.debug("sessionClosed()...");??
- ????????Connection?connection?=?(Connection)?session.getAttribute(CONNECTION);??
- ????????connection.close();??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?with?the?related?IdleStatus?when?a?connection?becomes?idle.?
- ?????*/??
- ????public?void?sessionIdle(IoSession?session,?IdleStatus?status)??
- ????????????throws?Exception?{??
- ????????log.debug("sessionIdle()...");??
- ????????Connection?connection?=?(Connection)?session.getAttribute(CONNECTION);??
- ????????if?(log.isDebugEnabled())?{??
- ????????????log.debug("Closing?connection?that?has?been?idle:?"?+?connection);??
- ????????}??
- ????????connection.close();??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?when?any?exception?is?thrown.?
- ?????*/??
- ????public?void?exceptionCaught(IoSession?session,?Throwable?cause)??
- ????????????throws?Exception?{??
- ????????log.debug("exceptionCaught()...");??
- ????????log.error(cause);??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?when?a?message?is?received.?
- ?????*/??
- ????public?void?messageReceived(IoSession?session,?Object?message)??
- ????????????throws?Exception?{??
- ????????log.debug("messageReceived()...");??
- ????????log.debug("RCVD:?"?+?message);??
- ??
- ????????//?Get?the?stanza?handler??
- ????????StanzaHandler?handler?=?(StanzaHandler)?session??
- ????????????????.getAttribute(STANZA_HANDLER);??
- ??
- ????????//?Get?the?XMPP?packet?parser??
- ????????int?hashCode?=?Thread.currentThread().hashCode();??
- ????????XMPPPacketReader?parser?=?parsers.get(hashCode);??
- ????????if?(parser?==?null)?{??
- ????????????parser?=?new?XMPPPacketReader();??
- ????????????parser.setXPPFactory(factory);??
- ????????????parsers.put(hashCode,?parser);??
- ????????}??
- ??
- ????????//?The?stanza?handler?processes?the?message??
- ????????try?{??
- ????????????handler.process((String)?message,?parser);??
- ????????}?catch?(Exception?e)?{??
- ????????????log.error(??
- ????????????????????"Closing?connection?due?to?error?while?processing?message:?"??
- ????????????????????????????+?message,?e);??
- ????????????Connection?connection?=?(Connection)?session??
- ????????????????????.getAttribute(CONNECTION);??
- ????????????connection.close();??
- ????????}??
- ????}??
- ??
- ????/**?
- ?????*?Invoked?when?a?message?written?by?IoSession.write(Object)?is?sent?out.?
- ?????*/??
- ????public?void?messageSent(IoSession?session,?Object?message)?throws?Exception?{??
- ????????log.debug("messageSent()...");??
- ????}??
- ??
- }??
?XmppIoHandler在加载的时候创建相关的xml解析工厂。
??????? sessionOpened:在连接打开时候创建相关的xml的解析器和Handler处理器。
??????? sessionClosed:关闭相关的连接。
??????? sessionIdle:关闭相关的连接。
??????? messageReceived:获取相关的xml解析器和handler处理器处理相关的消息。