Openfire连接的加载

Openfire重要的一项就是连接的加载,包括好多种连接。

        // 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());

1.载入

在所有的准备好之后在加载连接。 loadModule:

    /**
     * Loads a module.
     *
     * @param module the name of the class that implements the Module interface.
     */
    private void loadModule(String module) {
        try {
            Class<Module> modClass = (Class<Module>) loader.loadClass(module);
            Module mod = modClass.newInstance();
            this.modules.put(modClass, mod);
        }
        catch (Exception e) {
            e.printStackTrace();
            logger.error(LocaleUtils.getLocalizedString("admin.error"), e);
        }
    }

使用class.loadClass 然后newInstance创建实例对象

2.初始化

initModule: 每一个module都有继承BasicModule 然后有

方法列表 然后在加载

3.启动

startModule:

    @Override
    public void start() {
        super.start();
        startListeners();
        SocketSendingTracker.getInstance().start();
        CertificateManager.addListener(this);
    }

然后startListeners(); 方法其中有判断插件是否全部被加载了,如果不被没有被加载完全那么,就会递归的调用startListeners() 方法来启动监听。

        for ( final ConnectionListener listener : getListeners() )
        {
            try
            {
                listener.start();
            }
            catch ( RuntimeException ex )
            {
                Log.error( "An exception occurred while starting listener " + listener, ex );
            }
        }

挨个开启连接监听

        if ( getType() == ConnectionType.SOCKET_S2S )
        {
            System.out.println("看看还用不用喽");
            connectionAcceptor = new LegacyConnectionAcceptor( generateConnectionConfiguration() );
        }
        else
        {
            connectionAcceptor = new MINAConnectionAcceptor( generateConnectionConfiguration() );
        }

        connectionAcceptor.start();
        Log.info( "Started." );

上面的只有服务端对服务端的监听还在用。我们主要看看下面的MINAConnectionAcceptor的东西。

然后connectionAcceptor.start();

我们从资料就可以知道,Openfire是一个底层基于MINA的。在这里我们终于见到了MINA的真容啊真不容易。。

/**
     * Starts this acceptor by binding the socket acceptor. When the acceptor is already started, a warning will be
     * logged and the method invocation is otherwise ignored.
     */
    @Override
    public synchronized void start()
    {
        if ( socketAcceptor != null )
        {
            Log.warn( "Unable to start acceptor (it is already started!)" );
            return;
        }

        try
        {
            // Configure the thread pool that is to be used.
            final int initialSize = ( configuration.getMaxThreadPoolSize() / 4 ) + 1;
            final ExecutorFilter executorFilter = new ExecutorFilter( initialSize, configuration.getMaxThreadPoolSize(), 60, TimeUnit.SECONDS );
            final ThreadPoolExecutor eventExecutor = (ThreadPoolExecutor) executorFilter.getExecutor();
            final ThreadFactory threadFactory = new NamedThreadFactory( name + "-thread-", eventExecutor.getThreadFactory(), true, null );
            eventExecutor.setThreadFactory( threadFactory );

            // Construct a new socket acceptor, and configure it.
            socketAcceptor = buildSocketAcceptor();

            if ( JMXManager.isEnabled() )
            {
                configureJMX( socketAcceptor, name );
            }

            final DefaultIoFilterChainBuilder filterChain = socketAcceptor.getFilterChain();
            filterChain.addFirst( ConnectionManagerImpl.EXECUTOR_FILTER_NAME, executorFilter );

            // Add the XMPP codec filter
            filterChain.addAfter( ConnectionManagerImpl.EXECUTOR_FILTER_NAME, ConnectionManagerImpl.XMPP_CODEC_FILTER_NAME, new ProtocolCodecFilter( new XMPPCodecFactory() ) );

            // Kill sessions whose outgoing queues keep growing and fail to send traffic
            filterChain.addAfter( ConnectionManagerImpl.XMPP_CODEC_FILTER_NAME, ConnectionManagerImpl.CAPACITY_FILTER_NAME, new StalledSessionsFilter() );

            // Ports can be configured to start connections in SSL (as opposed to upgrade a non-encrypted socket to an encrypted one, typically using StartTLS)
            if ( configuration.getTlsPolicy() == Connection.TLSPolicy.legacyMode )
            {
                final SslFilter sslFilter = encryptionArtifactFactory.createServerModeSslFilter();
                filterChain.addAfter( ConnectionManagerImpl.EXECUTOR_FILTER_NAME, ConnectionManagerImpl.TLS_FILTER_NAME, sslFilter );
            }

            // Throttle sessions who send data too fast
            if ( configuration.getMaxBufferSize() > 0 )
            {
                socketAcceptor.getSessionConfig().setMaxReadBufferSize( configuration.getMaxBufferSize() );
                Log.debug( "Throttling read buffer for connections to max={} bytes", configuration.getMaxBufferSize() );
            }

            // Start accepting connections
            socketAcceptor.setHandler( connectionHandler );
            socketAcceptor.bind( new InetSocketAddress( configuration.getBindAddress(), configuration.getPort() ) );
        }
        catch ( Exception e )
        {
            System.err.println( "Error starting " + configuration.getPort() + ": " + e.getMessage() );
            Log.error( "Error starting: " + configuration.getPort(), e );
            // Reset for future use.
            if (socketAcceptor != null) {
                try {
                    socketAcceptor.unbind();
                } finally {
                    socketAcceptor = null;
                }
            }
        }
    }

如果看过MINA的API的话就会很容易理解上面这个过程

就是建立一个NioSocketAcceptor对象,然后进行一些操作,之后可以参考MINA的小DEMO

socketAcceptor.setHandler( connectionHandler );

MINA的框架交给这个业务类来处理消息

ConnectionHandler这个类就是我们来处理所有来自客户端的消息IO处理。

/**
 * An 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 <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class IoHandlerAdapter implements IoHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(IoHandlerAdapter.class);

    public void sessionCreated(IoSession session) throws Exception {
        // Empty handler
    }

    public void sessionOpened(IoSession session) throws Exception {
        // Empty handler
    }

    public void sessionClosed(IoSession session) throws Exception {
        // Empty handler
    }

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

    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 {
        // Empty handler
    }

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

results matching ""

    No results matching ""