openfire和mina(一)

来源:互联网 发布:阿里云怎么开放端口 编辑:程序博客网 时间:2024/06/13 02:27

      看了几天的openfire,网上的资料太少了,只有一个国外的网站不错,http://www.igniterealtime.org/,其他的只能自己摸索了。

openfire启动:

ServerStarter

会加载 org.jivesoftware.openfire.XMPPServer

在XMPPServer会加载一系列模块

其中的ConnectionManagerImpl 是连接模块

 // Load this module always last since we don't want to start listening for clients
        // before the rest of the modules have been started
        loadModule(ConnectionManagerImpl.class.getName());

ConnectionManagerImpl 会启动一系列的监听。

其中的createClientListeners和startClientListeners是我比较关心的,先看看再这里面openfire都做了什么!

 

private void createClientListeners() {
        // Start clients plain socket unless it's been disabled.
        if (isClientListenerEnabled()) {
            // Create SocketAcceptor with correct number of processors
            socketAcceptor = buildSocketAcceptor();
            // Customize Executor that will be used by processors to process incoming stanzas
            ExecutorThreadModel threadModel = ExecutorThreadModel.getInstance("client");
            int eventThreads = JiveGlobals.getIntProperty("xmpp.client.processing.threads", 16);
            ThreadPoolExecutor eventExecutor = (ThreadPoolExecutor)threadModel.getExecutor();
            eventExecutor.setCorePoolSize(eventThreads + 1);
            eventExecutor.setMaximumPoolSize(eventThreads + 1);
            eventExecutor.setKeepAliveTime(60, TimeUnit.SECONDS);

            socketAcceptor.getDefaultConfig().setThreadModel(threadModel);
            // Add the XMPP codec filter
            socketAcceptor.getFilterChain().addFirst("xmpp", new ProtocolCodecFilter(new XMPPCodecFactory()));
            // Kill sessions whose outgoing queues keep growing and fail to send traffic
            socketAcceptor.getFilterChain().addAfter("xmpp", "outCap", new StalledSessionsFilter());
        }
    }

对了这里就是和用的mian框架去做联网处理,首先设置mina框架的线程池,然后把由XMPPCodecFactory做为 ProtocolCodecFilter的chain添加到FilterChain中!

然后

 

private void startClientListeners(String localIPAddress) {
        // Start clients plain socket unless it's been disabled.
        if (isClientListenerEnabled()) {
            int port = getClientListenerPort();
            try {
                // Listen on a specific network interface if it has been set.
                String interfaceName = JiveGlobals.getXMLProperty("network.interface");
                InetAddress bindInterface = null;
                if (interfaceName != null) {
                    if (interfaceName.trim().length() > 0) {
                        bindInterface = InetAddress.getByName(interfaceName);
                    }
                }
                // Start accepting connections
                socketAcceptor
                        .bind(new InetSocketAddress(bindInterface, port), new ClientConnectionHandler(serverName));

                ports.add(new ServerPort(port, serverName, localIPAddress, false, null, ServerPort.Type.client));

                List<String> params = new ArrayList<String>();
                params.add(Integer.toString(port));
                Log.info(LocaleUtils.getLocalizedString("startup.plain", params));
            }
            catch (Exception e) {
                System.err.println("Error starting XMPP listener on port " + port + ": " +
                        e.getMessage());
                Log.error(LocaleUtils.getLocalizedString("admin.error.socket-setup"), e);
            }
        }
    }

 

 

  socketAcceptor
                        .bind(new InetSocketAddress(bindInterface, port), new ClientConnectionHandler(serverName));

ClientConnectionHandler作为数据处理

服务器去监听5222端口去了,mina真方便!

 

 

 关于MINA框架可以去网上找找资料,这里就不说了。

 

  这里要说下MINA中的IoHandler这个接口,IoHandler是最终面对用户的接口,看下这个接口中的方法:

 


 

public interface IoHandler {
    /**
     * Invoked from an I/O processor thread when a new connection has been created.
     * Because this method is supposed to be called from the same thread that
     * handles I/O of multiple sessions, please implement this method to perform
     * tasks that consumes minimal amount of time such as socket parameter
     * and user-defined session attribute initialization.
     */

    void sessionCreated(IoSession session) throws Exception;

    /**
     * Invoked when a connection has been opened.  This method is invoked after
     * {@link #sessionCreated(IoSession)}.  The biggest difference from
     * {@link #sessionCreated(IoSession)} is that it's invoked from other thread
     * than an I/O processor thread once thread model is configured properly.
     */

    void sessionOpened(IoSession session) throws Exception;

    /**
     * Invoked when a connection is closed.
     */

    void sessionClosed(IoSession session) throws Exception;

    /**
     * Invoked with the related {@link IdleStatus} when a connection becomes idle.
     * This method is not invoked if the transport type is UDP; it's a known bug,
     * and will be fixed in 2.0.
     */

    void sessionIdle(IoSession session, IdleStatus status) throws Exception;

    /**
     * Invoked when any exception is thrown by user {@link IoHandler}
     * implementation or by MINA.  If <code>cause</code> is an instance of
     * {@link IOException}, MINA will close the connection automatically.
     */

    void exceptionCaught(IoSession session, Throwable cause) throws Exception;

    /**
     * Invoked when a message is received.
     */

    void messageReceived(IoSession session, Object message) throws Exception;

    /**
     * Invoked when a message written by {@link IoSession#write(Object)} is
     * sent out.
     */

    void messageSent(IoSession session, Object message) throws Exception;
}

 

 


 

在mina中实现这个接口的类是IoHandlerAdapter 这个类

/**
 * An abstract adapter class for {@link IoHandler}.  You can extend this
 * class and selectively override required event handler methods only.  All
 * methods do nothing by default.
 *
 * @author The Apache MINA Project (dev@mina.apache.org)
 * @version $Rev: 671827 $, $Date: 2008-06-26 10:49:48 +0200 (jeu, 26 jun 2008) $
 */

public class IoHandlerAdapter implements IoHandler {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    public void sessionCreated(IoSession session) throws Exception {
    }

    public void sessionOpened(IoSession session) throws Exception {
    }

    public void sessionClosed(IoSession session) throws Exception {
    }

    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {
    }

    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        if (logger.isWarnEnabled()) {
            logger.warn("EXCEPTION, please implement "
                    + getClass().getName()
                    + ".exceptionCaught() for proper handling:", cause);
        }
    }

    public void messageReceived(IoSession session, Object message)
            throws Exception {
    }

    public void messageSent(IoSession session, Object message) throws Exception {
    }
}

 


 

接下来转到openfire,在openfire中ConnectionHandler类继承自IoHandlerAdapter,也就充当着最后要面对用户的角色。

public abstract class ConnectionHandler extends IoHandlerAdapter

 

      这个是ConnectionHandler的类图,可以看出他有3个子类,而其中的ClientConnectionHandler是处理客户端和服务器连接用到的,也是我先要说明的。

 


 

     当有客户端进行连接的时候MINA框架会调用IoHandler的sessionOpened(),

 

    public void sessionOpened(IoSession session) throws Exception {
        // Create a new XML parser for the new connection. The parser will be used by the XMPPDecoder filter.
        XMLLightweightParser parser = new XMLLightweightParser(CHARSET);
        session.setAttribute(XML_PARSER, parser);
        // Create a new NIOConnection for the new session
        NIOConnection connection = createNIOConnection(session);
        session.setAttribute(CONNECTION, connection);
        session.setAttribute(HANDLER, createStanzaHandler(connection));
        // Set the max time a connection can be idle before closing it
        int idleTime = getMaxIdleTime();
        if (idleTime > 0) {
            session.setIdleTime(IdleStatus.READER_IDLE, idleTime);
        }
    }
可以看到这里分别创建了XMLLightweightParser,NIOConnection,ClientStanzaHandler实例并将它们放到了session中

 


 

      当客户端往服务器发送消息的时候会调用IoHandler的messageReceived(IoSession session, Object message)

 

    public void messageReceived(IoSession session, Object message) throws Exception {
        // Get the stanza handler for this session
        StanzaHandler handler = (StanzaHandler) session.getAttribute(HANDLER);
        // Get the parser to use to process stanza. For optimization there is going
        // to be a parser for each running thread. Each Filter will be executed
        // by the Executor placed as the first Filter. So we can have a parser associated
        // to each Thread

        int hashCode = Thread.currentThread().hashCode();
        XMPPPacketReader parser = parsers.get(hashCode);
        if (parser == null) {
            parser = new XMPPPacketReader();
            parser.setXPPFactory(factory);
            parsers.put(hashCode, parser);
        }
        // Update counter of read btyes
        updateReadBytesCounter(session);
      System.out.println("RCVD: " + message);
        // Let the stanza handler process the received stanza
        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();
        }
    }
在这里得到了XMPPPacketReader 然后处理过来的XML数据。

到这里就完成了C------>S的数据传输,数据通过MINA层来到了XMPP层。

 


 

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 银行卡绑定太多微信了怎么办 怎样给qq设密码怎么办 吃了心悦胶囊上火怎么办 qq暂时被冻结了怎么办 部落群审核未通过怎么办 qq被限制解封该怎么办 微信提现成功但没到账怎么办 拍拍贷登录不上怎么办 京东店铺出租保证金怎么办 所选地区无货怎么办 闲鱼七天没发货怎么办 续贷密码忘了怎么办 微店商家不发货怎么办 微店商家不退钱怎么办 维修车辆被拍违章停车怎么办 网贷申请平台太多怎么办 所在城市没有网店怎么办信用卡 拍拍贷不放款了怎么办 拍拍贷账号注销了怎么办 我在拍拍贷注销了怎么办 快贷逾期一年了怎么办 广州车牌买新车旧车怎么办 高尔夫旅行款被锁在车内怎么办 英雄联盟误删文件怎么办 拍拍贷换了号码怎么办 手机打开显示无法连接服务器怎么办 剑灵画面卡顿怎么办 cf被永久禁赛了怎么办 微信没有微游戏商店怎么办 游侠云盒下载慢怎么办2018 安卓手机玩网页游戏卡怎么办 safari点开什么都没有怎么办 康佳电视全网搜索打不开怎么办 脚被图钉扎了怎么办 电脑中毒了打不开软件怎么办 剑三程序不兼容怎么办 玩无主之地卡怎么办 平台老板跑路了怎么办 qq在苹果下载不了怎么办 下载速度快上传速度慢怎么办 苹果7开网页慢怎么办