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

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

Mina中源代码如下:

Java代码 收藏代码
  1. packageorg.apache.mina.core.service;
  2. importjava.io.IOException;
  3. importorg.apache.mina.core.session.IdleStatus;
  4. importorg.apache.mina.core.session.IoSession;
  5. /**
  6. *HandlesallI/OeventsfiredbyMINA.
  7. *
  8. *@author<ahref="http://mina.apache.org">ApacheMINAProject</a>
  9. *
  10. *@seeIoHandlerAdapter
  11. */
  12. publicinterfaceIoHandler{
  13. /**
  14. *InvokedfromanI/Oprocessorthreadwhenanewconnectionhasbeencreated.
  15. *Becausethismethodissupposedtobecalledfromthesamethreadthat
  16. *handlesI/Oofmultiplesessions,pleaseimplementthismethodtoperform
  17. *tasksthatconsumesminimalamountoftimesuchassocketparameter
  18. *anduser-definedsessionattributeinitialization.
  19. */
  20. voidsessionCreated(IoSessionsession)throwsException;
  21. /**
  22. *Invokedwhenaconnectionhasbeenopened.Thismethodisinvokedafter
  23. *{@link#sessionCreated(IoSession)}.Thebiggestdifferencefrom
  24. *{@link#sessionCreated(IoSession)}isthatit'sinvokedfromotherthread
  25. *thananI/Oprocessorthreadoncethreadmodelisconfiguredproperly.
  26. */
  27. voidsessionOpened(IoSessionsession)throwsException;
  28. /**
  29. *Invokedwhenaconnectionisclosed.
  30. */
  31. voidsessionClosed(IoSessionsession)throwsException;
  32. /**
  33. *Invokedwiththerelated{@linkIdleStatus}whenaconnectionbecomesidle.
  34. *ThismethodisnotinvokedifthetransporttypeisUDP;it'saknownbug,
  35. *andwillbefixedin2.0.
  36. */
  37. voidsessionIdle(IoSessionsession,IdleStatusstatus)throwsException;
  38. /**
  39. *Invokedwhenanyexceptionisthrownbyuser{@linkIoHandler}
  40. *implementationorbyMINA.If<code>cause</code>isaninstanceof
  41. *{@linkIOException},MINAwillclosetheconnectionautomatically.
  42. */
  43. voidexceptionCaught(IoSessionsession,Throwablecause)throwsException;
  44. /**
  45. *Invokedwhenamessageisreceived.
  46. */
  47. voidmessageReceived(IoSessionsession,Objectmessage)throwsException;
  48. /**
  49. *Invokedwhenamessagewrittenby{@linkIoSession#write(Object)}is
  50. *sentout.
  51. */
  52. voidmessageSent(IoSessionsession,Objectmessage)throwsException;
  53. }

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. packageorg.androidpn.server.xmpp.net;
  2. importjava.util.Map;
  3. importjava.util.concurrent.ConcurrentHashMap;
  4. importorg.androidpn.server.xmpp.XmppServer;
  5. importorg.apache.commons.logging.Log;
  6. importorg.apache.commons.logging.LogFactory;
  7. importorg.apache.mina.core.service.IoHandler;
  8. importorg.apache.mina.core.session.IdleStatus;
  9. importorg.apache.mina.core.session.IoSession;
  10. importorg.dom4j.io.XMPPPacketReader;
  11. importorg.jivesoftware.openfire.net.MXParser;
  12. importorg.jivesoftware.openfire.nio.XMLLightweightParser;
  13. importorg.xmlpull.v1.XmlPullParserException;
  14. importorg.xmlpull.v1.XmlPullParserFactory;
  15. /**
  16. *Thisclassistocreatenewsessions,destroysessionsanddeliver
  17. *receivedXMLstanzastotheStanzaHandler.
  18. *
  19. *@authorSehwanNoh(devnoh@gmail.com)
  20. */
  21. publicclassXmppIoHandlerimplementsIoHandler{
  22. privatestaticfinalLoglog=LogFactory.getLog(XmppIoHandler.class);
  23. publicstaticfinalStringXML_PARSER="XML_PARSER";
  24. privatestaticfinalStringCONNECTION="CONNECTION";
  25. privatestaticfinalStringSTANZA_HANDLER="STANZA_HANDLER";
  26. privateStringserverName;
  27. privatestaticMap<Integer,XMPPPacketReader>parsers=newConcurrentHashMap<Integer,XMPPPacketReader>();
  28. privatestaticXmlPullParserFactoryfactory=null;
  29. static{
  30. try{
  31. factory=XmlPullParserFactory.newInstance(
  32. MXParser.class.getName(),null);
  33. factory.setNamespaceAware(true);
  34. }catch(XmlPullParserExceptione){
  35. log.error("Errorcreatingaparserfactory",e);
  36. }
  37. }
  38. /**
  39. *Constructor.Settheservernamefromserverinstance.
  40. */
  41. protectedXmppIoHandler(){
  42. serverName=XmppServer.getInstance().getServerName();
  43. }
  44. /**
  45. *InvokedfromanI/Oprocessorthreadwhenanewconnectionhasbeencreated.
  46. */
  47. publicvoidsessionCreated(IoSessionsession)throwsException{
  48. log.debug("sessionCreated()...");
  49. }
  50. /**
  51. *Invokedwhenaconnectionhasbeenopened.
  52. */
  53. publicvoidsessionOpened(IoSessionsession)throwsException{
  54. log.debug("sessionOpened()...");
  55. log.debug("remoteAddress="+session.getRemoteAddress());
  56. //CreateanewXMLparser
  57. XMLLightweightParserparser=newXMLLightweightParser("UTF-8");
  58. session.setAttribute(XML_PARSER,parser);
  59. //Createanewconnection
  60. Connectionconnection=newConnection(session);
  61. session.setAttribute(CONNECTION,connection);
  62. session.setAttribute(STANZA_HANDLER,newStanzaHandler(serverName,
  63. connection));
  64. }
  65. /**
  66. *Invokedwhenaconnectionisclosed.
  67. */
  68. publicvoidsessionClosed(IoSessionsession)throwsException{
  69. log.debug("sessionClosed()...");
  70. Connectionconnection=(Connection)session.getAttribute(CONNECTION);
  71. connection.close();
  72. }
  73. /**
  74. *InvokedwiththerelatedIdleStatuswhenaconnectionbecomesidle.
  75. */
  76. publicvoidsessionIdle(IoSessionsession,IdleStatusstatus)
  77. throwsException{
  78. log.debug("sessionIdle()...");
  79. Connectionconnection=(Connection)session.getAttribute(CONNECTION);
  80. if(log.isDebugEnabled()){
  81. log.debug("Closingconnectionthathasbeenidle:"+connection);
  82. }
  83. connection.close();
  84. }
  85. /**
  86. *Invokedwhenanyexceptionisthrown.
  87. */
  88. publicvoidexceptionCaught(IoSessionsession,Throwablecause)
  89. throwsException{
  90. log.debug("exceptionCaught()...");
  91. log.error(cause);
  92. }
  93. /**
  94. *Invokedwhenamessageisreceived.
  95. */
  96. publicvoidmessageReceived(IoSessionsession,Objectmessage)
  97. throwsException{
  98. log.debug("messageReceived()...");
  99. log.debug("RCVD:"+message);
  100. //Getthestanzahandler
  101. StanzaHandlerhandler=(StanzaHandler)session
  102. .getAttribute(STANZA_HANDLER);
  103. //GettheXMPPpacketparser
  104. inthashCode=Thread.currentThread().hashCode();
  105. XMPPPacketReaderparser=parsers.get(hashCode);
  106. if(parser==null){
  107. parser=newXMPPPacketReader();
  108. parser.setXPPFactory(factory);
  109. parsers.put(hashCode,parser);
  110. }
  111. //Thestanzahandlerprocessesthemessage
  112. try{
  113. handler.process((String)message,parser);
  114. }catch(Exceptione){
  115. log.error(
  116. "Closingconnectionduetoerrorwhileprocessingmessage:"
  117. +message,e);
  118. Connectionconnection=(Connection)session
  119. .getAttribute(CONNECTION);
  120. connection.close();
  121. }
  122. }
  123. /**
  124. *InvokedwhenamessagewrittenbyIoSession.write(Object)issentout.
  125. */
  126. publicvoidmessageSent(IoSessionsession,Objectmessage)throwsException{
  127. log.debug("messageSent()...");
  128. }
  129. }

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

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

sessionClosed:关闭相关的连接。

sessionIdle:关闭相关的连接。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值