mina-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sven Panko <Sven.Pa...@proximity.de>
Subject Problem with IoHandler messageSent/messageReceived
Date Thu, 14 Sep 2006 17:50:14 GMT
Hello all,

I am using Mina 0.9.5 in a client/server app and experience a strange 
problem with my implementation of the IoHandler: whenever I send a 
message, it passes my encoder just fine and log statements indicate that 
the message is properly written out. After that I put a log statement in 
the messageSent() method of my IoHandler implementation - but this method 
gets called several times for one single message. The reverse is true for 
the receiver. The message decoder reads the data correctly and logs 
whenever a message was received in its entirety. After that 
messageReceived is invoked several times for the same message. I don't 
have a clue if that is correct but I do not think so.

My server starts like this:

                                SSLFilter sslFilter = new 
SSLFilter(this.sslContextFactory.getServerContext());

                                sslFilter.setNeedClientAuth(true);
                                sslFilter.setWantClientAuth(true);

                                IoAcceptorConfig config = new 
SocketAcceptorConfig();
                                DefaultIoFilterChainBuilder chain = 
config.getFilterChain();

                                SocketAcceptor acceptor = new 
SocketAcceptor();

                                ThreadPoolFilter ioThreadPoolFilter = new 
ThreadPoolFilter();
                                ThreadPoolFilter protocolThreadPoolFilter 
= new ThreadPoolFilter();

                                chain.addFirst("ioThreadPool", 
ioThreadPoolFilter);
                                chain.addLast("protocolThreadPool", 
protocolThreadPoolFilter);
                                chain.addLast("sslFilter", sslFilter);

                                acceptor.bind(<socketAddress>, new 
GenericSessionHandler(this), config);

My clients connect to the server like this:

                        ThreadPoolFilter ioThreadPoolFilter = new 
ThreadPoolFilter();
                        ThreadPoolFilter protocolThreadPoolFilter = new 
ThreadPoolFilter();

                        // get an SSL client context
                        SSLFilter sslFilter = new 
SSLFilter(this.sslContext.getClientContext());

                        sslFilter.setUseClientMode(true);

                        // create the session (the connector gets reused 
after sessions are closed)
                        this.connector = new SocketConnector();

                        // set the timeout
                        ((IoConnectorConfig) 
connector.getDefaultConfig()).setConnectTimeout(60);
 connector.getFilterChain().addFirst("ioThreadPool", ioThreadPoolFilter); 
 connector.getFilterChain().addLast("protocolThreadPool", 
protocolThreadPoolFilter);
                        connector.getFilterChain().addLast("sslFilter", 
sslFilter); 
 
                        ConnectFuture future = connector.connect(new 
InetSocketAddress(address, port, new GenericSessionHandler(this));

                        // wait until the connection is established
                        future.join();

                        // the connection should be established by now...
                        if (!future.isConnected())
                                throw new 
CommunicationServiceException("...");
 
                        // use this session
                        this.session = future.getSession();

The generic session handler is the same for client and server and looks 
like this:

public class GenericSessionHandler implements IoHandler {
        private final Log logger = 
LogFactory.getLog(GenericSessionHandler.class);

        private final SessionStateListener listener;

        public GenericSessionHandler(SessionStateListener ssl) {
                this.listener = ssl;
        }

        public void sessionCreated(IoSession session) throws Exception {
                ProtocolCodecFactory codec = new SimpleFactory();
                session.getFilterChain().addLast("protocolFilter",
                                new ProtocolCodecFilter(codec));

                if (logger.isDebugEnabled()) {
                        logger
                                        .debug(MessageFormat
                                                        .format(
                                                                        "a 
new communication session was created with peer at address {0}",
 session.getRemoteAddress()));
                }
        }

        public void sessionOpened(IoSession session) throws Exception {
                if (logger.isDebugEnabled()) {
                        logger
                                        .debug(MessageFormat
                                                        .format(
                                                                        "a 
communication session was opened with peer at address {0}",
 session.getRemoteAddress()));
                }

                this.listener.sessionCreated(session);
        }

        public void sessionClosed(IoSession session) throws Exception {
                if (logger.isDebugEnabled()) {
                        logger
                                        .debug(MessageFormat
                                                        .format(
 "communication session was closed with peer at address {0} - amount of 
data transferred was {1} byte(s)",
 session.getRemoteAddress(), session
        .getWrittenBytes()));
                }

                this.listener.sessionClosed(session);
        }

        public void sessionIdle(IoSession session, IdleStatus status)
                        throws Exception {
                this.listener.sessionIdle(session, status);
        }

        private void closeSession(IoSession session) {
                try {
                        session.close();
                } catch (Exception e) {
                        logger.error("exception while closing session", 
e);


                        this.listener.sessionClosed(session);
                }
        }

        public void exceptionCaught(IoSession session, Throwable e)
                        throws Exception {

                if (logger.isDebugEnabled()) {
                        logger.debug("caught exception while processing 
session", e);
                }

                this.listener.sessionException(session, e);

                closeSession(session);
        }

        public void messageReceived(IoSession session, Object message)
                        throws Exception {
                if (!(message instanceof Envelope)) {
                        if (logger.isDebugEnabled()) {
                                logger.debug(MessageFormat.format(
                                                "received unknown object 
from peer: {0}", message));
                        }
                        return;
                }
 
                if (logger.isDebugEnabled()) {
                        logger.debug(MessageFormat.format("message 
received with UID = {0} and type = {1}", ((Envelope) 
message).getRequestUid(), ((Envelope) message).getType()));
                }

                this.listener.objectReceived(session, message);
        }

        public void messageSent(IoSession session, Object message) throws 
Exception {
                if (logger.isDebugEnabled()) {
                        logger.debug(MessageFormat.format("message sent 
with UID = {0} and type = {1}", ((Envelope) message).getRequestUid(), 
((Envelope) message).getType()));
                }
        }

}

(note that Envelope is the base class of all my messages and contains a 
UID)

I would never have bothered to post this here because the system worked 
fine for more than 4 month. But recently I upgraded to Mina 0.9.5 and 
experienced another strange problem: sometimes the last message of a 
communication session is received by the client when it tries to send 
another message to the server. This occurs only randomly and always 
affects the last message. My client is only able to receive that last 
message when it sends another message - is this behaviour intended?

Sorry for the long post, but I am stuck here...

Thanks in advance,

Sven



Information contained in this message is confidential and may be legally privileged. If you
are not the addressee indicated in this message (or responsible for the delivery of the message
to such person), you may not copy, disclose or deliver this message or any part of it to anyone,
in any form. In such case, you should delete this message and kindly notify the sender by
reply Email. Opinions, conclusions and other information in this message that do not relate
to the official business of Proximity shall be understood as neither given nor endorsed by
it.

Mime
View raw message