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.  * @author <a href="http://mina.apache.org">Apache MINA Project</a> 
  12.  * 
  13.  * @see IoHandlerAdapter 
  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.      * {@link #sessionCreated(IoSession)}.  The biggest difference from 
  28.      * {@link #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.      * Invoked with the related {@link IdleStatus} 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 {@link IoHandler} 
  47.      * implementation or by MINA.  If <code>cause</code> is an instance of 
  48.      * {@link IOException}, 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.      * Invoked when a message written by {@link IoSession#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.  * @author Sehwan Noh (devnoh@gmail.com) 
  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处理器处理相关的消息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值