androidpn의 학습 연구(8)androidpn에서 업무류 XmppIoHandler 실현 분석

10399 단어 AndroidPnXMPPIoHandler
androidpn에서 주로 미나를 이용하여 인터넷 통신을 하는데 그 중에서 미나에서 IoHandler는 주요한 업무 논리를 처리하는 데 사용된다.
미나의 소스 코드는 다음과 같습니다.
package org.apache.mina.core.service;

import java.io.IOException;

import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

/**
 * Handles all I/O events fired by MINA.
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 *
 * @see IoHandlerAdapter
 */
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;
}

 

미나에서 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)
Client에서 IoSession이 보낸 데이터를 받으면 콜백
messageSent(IoSession,Object)
IoSession에 전송된 Client 데이터가 성공적으로 전송되었을 때 콜백
exceptionCaught(IoSession,Throwable)
세션 중 이상이 발생했을 때, 보통 오류 처리에 사용됩니다.
 
 
 
session.write (Object) 방법은 비동기적인 방법으로 이 방법의 호출이 막히지 않고 미나에게 비동기적인 쓰기 동작을 보내고, 이미 전송된 비동기적인 쓰기 동작을 제어할 수 있는 WriteFuture 대상을 되돌려줍니다.예를 들어 WriteFuture의 await () 또는 awaitUninterruptibly () 를 호출하면 이 비동기 동작이 끝날 때까지 동기화할 수 있습니다.
 
입출력 프로세서에서 업무 논리를 실현할 때 간단한 경우 메시지 Received에서 전송된 메시지를 처리하기만 하면 된다.등체에 데이터를 다시 쓸 필요가 있으면 IoSession을 사용하십시오.write()만 있으면 됩니다.
또한 클라이언트와 서버의 통신 프로토콜은 비교적 복잡하고 클라이언트는 상태 변천이 있다. 이때 미나가 제공하는 상태기로 실현할 수 있고 IO프로세서로 실현할 수 있어 더욱 간단하다.
 
androidpn의 XmppIoHandler 소스 코드:
package org.androidpn.server.xmpp.net;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.androidpn.server.xmpp.XmppServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.dom4j.io.XMPPPacketReader;
import org.jivesoftware.openfire.net.MXParser;
import org.jivesoftware.openfire.nio.XMLLightweightParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;

/** 
 * This class is to create new sessions, destroy sessions and deliver
 * received XML stanzas to the StanzaHandler.
 *
 * @author Sehwan Noh ([email protected])
 */
public class XmppIoHandler implements IoHandler {

    private static final Log log = LogFactory.getLog(XmppIoHandler.class);

    public static final String XML_PARSER = "XML_PARSER";

    private static final String CONNECTION = "CONNECTION";

    private static final String STANZA_HANDLER = "STANZA_HANDLER";

    private String serverName;

    private static Map<Integer, XMPPPacketReader> parsers = new ConcurrentHashMap<Integer, XMPPPacketReader>();

    private static XmlPullParserFactory factory = null;

    static {
        try {
            factory = XmlPullParserFactory.newInstance(
                    MXParser.class.getName(), null);
            factory.setNamespaceAware(true);
        } catch (XmlPullParserException e) {
            log.error("Error creating a parser factory", e);
        }
    }

    /**
     * Constructor. Set the server name from server instance. 
     */
    protected XmppIoHandler() {
        serverName = XmppServer.getInstance().getServerName();
    }

    /**
     * Invoked from an I/O processor thread when a new connection has been created.
     */
    public void sessionCreated(IoSession session) throws Exception {
        log.debug("sessionCreated()...");
    }

    /**
     * Invoked when a connection has been opened.
     */
    public void sessionOpened(IoSession session) throws Exception {
        log.debug("sessionOpened()...");
        log.debug("remoteAddress=" + session.getRemoteAddress());
        // Create a new XML parser
        XMLLightweightParser parser = new XMLLightweightParser("UTF-8");
        session.setAttribute(XML_PARSER, parser);
        // Create a new connection
        Connection connection = new Connection(session);
        session.setAttribute(CONNECTION, connection);
        session.setAttribute(STANZA_HANDLER, new StanzaHandler(serverName,
                connection));
    }

    /**
     * Invoked when a connection is closed.
     */
    public void sessionClosed(IoSession session) throws Exception {
        log.debug("sessionClosed()...");
        Connection connection = (Connection) session.getAttribute(CONNECTION);
        connection.close();
    }

    /**
     * Invoked with the related IdleStatus when a connection becomes idle.
     */
    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {
        log.debug("sessionIdle()...");
        Connection connection = (Connection) session.getAttribute(CONNECTION);
        if (log.isDebugEnabled()) {
            log.debug("Closing connection that has been idle: " + connection);
        }
        connection.close();
    }

    /**
     * Invoked when any exception is thrown.
     */
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        log.debug("exceptionCaught()...");
        log.error(cause);
    }

    /**
     * Invoked when a message is received.
     */
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        log.debug("messageReceived()...");
        log.debug("RCVD: " + message);

        // Get the stanza handler
        StanzaHandler handler = (StanzaHandler) session
                .getAttribute(STANZA_HANDLER);

        // Get the XMPP packet parser
        int hashCode = Thread.currentThread().hashCode();
        XMPPPacketReader parser = parsers.get(hashCode);
        if (parser == null) {
            parser = new XMPPPacketReader();
            parser.setXPPFactory(factory);
            parsers.put(hashCode, parser);
        }

        // The stanza handler processes the message
        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();
        }
    }

    /**
     * Invoked when a message written by IoSession.write(Object) is sent out.
     */
    public void messageSent(IoSession session, Object message) throws Exception {
        log.debug("messageSent()...");
    }

}

XmppIoHandler는 불러올 때 관련 xml 분석 공장을 만듭니다.
sessionOpened: 연결이 열릴 때 관련 xml 해상도와Handler 프로세서를 만듭니다.
sessionClosed: 연관된 연결을 닫습니다.
sessionIdle: 연결된 연결을 닫습니다.
메시지 Received: xml 해상도와handler 프로세서 처리에 대한 정보를 가져옵니다.

좋은 웹페이지 즐겨찾기