当前位置: 代码迷 >> Android >> androidpn的学习研究(8)androidpn 中业务类XmppIoHandler实现分析
  详细解决方案

androidpn的学习研究(8)androidpn 中业务类XmppIoHandler实现分析

热度:103   发布时间:2016-04-28 06:40:29.0
androidpn的学习研究(八)androidpn 中业务类XmppIoHandler实现分析

?在androidpn中主要采用Mina进行网络通讯,其中Mina中IoHandler用来处理主要的业务逻辑。

Mina?中源代码如下:

Java代码??收藏代码
  1. package?org.apache.mina.core.service;??
  2. ??
  3. import?java.io.IOException;??
  4. ??
  5. import?org.apache.mina.core.session.IdleStatus;??
  6. import?org.apache.mina.core.session.IoSession;??
  7. ??
  8. /**?
  9. ?*?Handles?all?I/O?events?fired?by?MINA.?
  10. ?*?
  11. [email protected]<a?href="http://mina.apache.org">Apache?MINA?Project</a>?
  12. ?*?
  13. [email protected]?
  14. ?*/??
  15. public?interface?IoHandler?{??
  16. ????/**?
  17. ?????*?Invoked?from?an?I/O?processor?thread?when?a?new?connection?has?been?created.?
  18. ?????*?Because?this?method?is?supposed?to?be?called?from?the?same?thread?that?
  19. ?????*?handles?I/O?of?multiple?sessions,?please?implement?this?method?to?perform?
  20. ?????*?tasks?that?consumes?minimal?amount?of?time?such?as?socket?parameter?
  21. ?????*?and?user-defined?session?attribute?initialization.?
  22. ?????*/??
  23. ????void?sessionCreated(IoSession?session)?throws?Exception;??
  24. ??
  25. ????/**?
  26. ?????*?Invoked?when?a?connection?has?been?opened.??This?method?is?invoked?after?
  27. [email protected]#sessionCreated(IoSession)}.??The?biggest?difference?from?
  28. [email protected]#sessionCreated(IoSession)}?is?that?it's?invoked?from?other?thread?
  29. ?????*?than?an?I/O?processor?thread?once?thread?model?is?configured?properly.?
  30. ?????*/??
  31. ????void?sessionOpened(IoSession?session)?throws?Exception;??
  32. ??
  33. ????/**?
  34. ?????*?Invoked?when?a?connection?is?closed.?
  35. ?????*/??
  36. ????void?sessionClosed(IoSession?session)?throws?Exception;??
  37. ??
  38. ????/**?
  39. [email protected]}?when?a?connection?becomes?idle.?
  40. ?????*?This?method?is?not?invoked?if?the?transport?type?is?UDP;?it's?a?known?bug,?
  41. ?????*?and?will?be?fixed?in?2.0.?
  42. ?????*/??
  43. ????void?sessionIdle(IoSession?session,?IdleStatus?status)?throws?Exception;??
  44. ??
  45. ????/**?
  46. ?????*?Invoked?when?any?exception?is?thrown?by?user?[email protected]}?
  47. ?????*?implementation?or?by?MINA.??If?<code>cause</code>?is?an?instance?of?
  48. [email protected]},?MINA?will?close?the?connection?automatically.?
  49. ?????*/??
  50. ????void?exceptionCaught(IoSession?session,?Throwable?cause)?throws?Exception;??
  51. ??
  52. ????/**?
  53. ?????*?Invoked?when?a?message?is?received.?
  54. ?????*/??
  55. ????void?messageReceived(IoSession?session,?Object?message)?throws?Exception;??
  56. ??
  57. ????/**?
  58. [email protected]ssion#write(Object)}?is?
  59. ?????*?sent?out.?
  60. ?????*/??
  61. ????void?messageSent(IoSession?session,?Object?message)?throws?Exception;??
  62. }??

?

Mina中IoHandler可供处理的事件回调

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源代码:

Java代码??收藏代码
  1. package?org.androidpn.server.xmpp.net;??
  2. ??
  3. import?java.util.Map;??
  4. import?java.util.concurrent.ConcurrentHashMap;??
  5. ??
  6. import?org.androidpn.server.xmpp.XmppServer;??
  7. import?org.apache.commons.logging.Log;??
  8. import?org.apache.commons.logging.LogFactory;??
  9. import?org.apache.mina.core.service.IoHandler;??
  10. import?org.apache.mina.core.session.IdleStatus;??
  11. import?org.apache.mina.core.session.IoSession;??
  12. import?org.dom4j.io.XMPPPacketReader;??
  13. import?org.jivesoftware.openfire.net.MXParser;??
  14. import?org.jivesoftware.openfire.nio.XMLLightweightParser;??
  15. import?org.xmlpull.v1.XmlPullParserException;??
  16. import?org.xmlpull.v1.XmlPullParserFactory;??
  17. ??
  18. /**??
  19. ?*?This?class?is?to?create?new?sessions,?destroy?sessions?and?deliver?
  20. ?*?received?XML?stanzas?to?the?StanzaHandler.?
  21. ?*?
  22. [email protected]([email protected])?
  23. ?*/??
  24. public?class?XmppIoHandler?implements?IoHandler?{??
  25. ??
  26. ????private?static?final?Log?log?=?LogFactory.getLog(XmppIoHandler.class);??
  27. ??
  28. ????public?static?final?String?XML_PARSER?=?"XML_PARSER";??
  29. ??
  30. ????private?static?final?String?CONNECTION?=?"CONNECTION";??
  31. ??
  32. ????private?static?final?String?STANZA_HANDLER?=?"STANZA_HANDLER";??
  33. ??
  34. ????private?String?serverName;??
  35. ??
  36. ????private?static?Map<Integer,?XMPPPacketReader>?parsers?=?new?ConcurrentHashMap<Integer,?XMPPPacketReader>();??
  37. ??
  38. ????private?static?XmlPullParserFactory?factory?=?null;??
  39. ??
  40. ????static?{??
  41. ????????try?{??
  42. ????????????factory?=?XmlPullParserFactory.newInstance(??
  43. ????????????????????MXParser.class.getName(),?null);??
  44. ????????????factory.setNamespaceAware(true);??
  45. ????????}?catch?(XmlPullParserException?e)?{??
  46. ????????????log.error("Error?creating?a?parser?factory",?e);??
  47. ????????}??
  48. ????}??
  49. ??
  50. ????/**?
  51. ?????*?Constructor.?Set?the?server?name?from?server?instance.??
  52. ?????*/??
  53. ????protected?XmppIoHandler()?{??
  54. ????????serverName?=?XmppServer.getInstance().getServerName();??
  55. ????}??
  56. ??
  57. ????/**?
  58. ?????*?Invoked?from?an?I/O?processor?thread?when?a?new?connection?has?been?created.?
  59. ?????*/??
  60. ????public?void?sessionCreated(IoSession?session)?throws?Exception?{??
  61. ????????log.debug("sessionCreated()...");??
  62. ????}??
  63. ??
  64. ????/**?
  65. ?????*?Invoked?when?a?connection?has?been?opened.?
  66. ?????*/??
  67. ????public?void?sessionOpened(IoSession?session)?throws?Exception?{??
  68. ????????log.debug("sessionOpened()...");??
  69. ????????log.debug("remoteAddress="?+?session.getRemoteAddress());??
  70. ????????//?Create?a?new?XML?parser??
  71. ????????XMLLightweightParser?parser?=?new?XMLLightweightParser("UTF-8");??
  72. ????????session.setAttribute(XML_PARSER,?parser);??
  73. ????????//?Create?a?new?connection??
  74. ????????Connection?connection?=?new?Connection(session);??
  75. ????????session.setAttribute(CONNECTION,?connection);??
  76. ????????session.setAttribute(STANZA_HANDLER,?new?StanzaHandler(serverName,??
  77. ????????????????connection));??
  78. ????}??
  79. ??
  80. ????/**?
  81. ?????*?Invoked?when?a?connection?is?closed.?
  82. ?????*/??
  83. ????public?void?sessionClosed(IoSession?session)?throws?Exception?{??
  84. ????????log.debug("sessionClosed()...");??
  85. ????????Connection?connection?=?(Connection)?session.getAttribute(CONNECTION);??
  86. ????????connection.close();??
  87. ????}??
  88. ??
  89. ????/**?
  90. ?????*?Invoked?with?the?related?IdleStatus?when?a?connection?becomes?idle.?
  91. ?????*/??
  92. ????public?void?sessionIdle(IoSession?session,?IdleStatus?status)??
  93. ????????????throws?Exception?{??
  94. ????????log.debug("sessionIdle()...");??
  95. ????????Connection?connection?=?(Connection)?session.getAttribute(CONNECTION);??
  96. ????????if?(log.isDebugEnabled())?{??
  97. ????????????log.debug("Closing?connection?that?has?been?idle:?"?+?connection);??
  98. ????????}??
  99. ????????connection.close();??
  100. ????}??
  101. ??
  102. ????/**?
  103. ?????*?Invoked?when?any?exception?is?thrown.?
  104. ?????*/??
  105. ????public?void?exceptionCaught(IoSession?session,?Throwable?cause)??
  106. ????????????throws?Exception?{??
  107. ????????log.debug("exceptionCaught()...");??
  108. ????????log.error(cause);??
  109. ????}??
  110. ??
  111. ????/**?
  112. ?????*?Invoked?when?a?message?is?received.?
  113. ?????*/??
  114. ????public?void?messageReceived(IoSession?session,?Object?message)??
  115. ????????????throws?Exception?{??
  116. ????????log.debug("messageReceived()...");??
  117. ????????log.debug("RCVD:?"?+?message);??
  118. ??
  119. ????????//?Get?the?stanza?handler??
  120. ????????StanzaHandler?handler?=?(StanzaHandler)?session??
  121. ????????????????.getAttribute(STANZA_HANDLER);??
  122. ??
  123. ????????//?Get?the?XMPP?packet?parser??
  124. ????????int?hashCode?=?Thread.currentThread().hashCode();??
  125. ????????XMPPPacketReader?parser?=?parsers.get(hashCode);??
  126. ????????if?(parser?==?null)?{??
  127. ????????????parser?=?new?XMPPPacketReader();??
  128. ????????????parser.setXPPFactory(factory);??
  129. ????????????parsers.put(hashCode,?parser);??
  130. ????????}??
  131. ??
  132. ????????//?The?stanza?handler?processes?the?message??
  133. ????????try?{??
  134. ????????????handler.process((String)?message,?parser);??
  135. ????????}?catch?(Exception?e)?{??
  136. ????????????log.error(??
  137. ????????????????????"Closing?connection?due?to?error?while?processing?message:?"??
  138. ????????????????????????????+?message,?e);??
  139. ????????????Connection?connection?=?(Connection)?session??
  140. ????????????????????.getAttribute(CONNECTION);??
  141. ????????????connection.close();??
  142. ????????}??
  143. ????}??
  144. ??
  145. ????/**?
  146. ?????*?Invoked?when?a?message?written?by?IoSession.write(Object)?is?sent?out.?
  147. ?????*/??
  148. ????public?void?messageSent(IoSession?session,?Object?message)?throws?Exception?{??
  149. ????????log.debug("messageSent()...");??
  150. ????}??
  151. ??
  152. }??

?XmppIoHandler在加载的时候创建相关的xml解析工厂。

??????? sessionOpened:在连接打开时候创建相关的xml的解析器和Handler处理器。

??????? sessionClosed:关闭相关的连接。

??????? sessionIdle:关闭相关的连接。

??????? messageReceived:获取相关的xml解析器和handler处理器处理相关的消息。

<!-- Baidu Button BEGIN -->