26
votes

My client-server app works with Apache MINA at both, client and server sides. Sending data via UDP works OK, but after a minute server closes the connection (or MINA's way - "session") and stops answering.

The strange part is that the connection is active the whole time. Client is sending data every 1000ms and server answers to it with the same data. I've found a MINA's mechanism to destroying inactive sessions ExpiringMap, it's got a default value for session's time-to-live public static final int DEFAULT_TIME_TO_LIVE = 60; but I haven't found a way how to change it or better, update time-to-live for sessions.

Imho the time-to-live should update automatically with every incoming packet but I couldn't find a thing why isn't it my server doing. Should I say explicitly that I don't want it to destroy the session yet or what?

My code is quite similar to MINA's tutorials:

SERVER

IoAcceptor acceptor = new NioDatagramAcceptor();
try {
    acceptor.setHandler( new UDPHandler() );
    acceptor.bind( new InetSocketAddress(RelayConfig.getInstance().getUdpPort()) );

    acceptor.getSessionConfig().setReadBufferSize( 2048 );
    acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, IDLE_PERIOD );
    System.out.println("RELAY ["+RelayConfig.getInstance().getId()+"]: initialized!");
} catch (IOException e) {
    System.out.println("RELAY ["+RelayConfig.getInstance().getId()+"]: failed: "+e.getLocalizedMessage());
    //e.printStackTrace();
}

CLIENT

NioDatagramConnector connector = new NioDatagramConnector();
connector.getSessionConfig().setUseReadOperation(true);

handler = new UDPHandler();
connector.setHandler(handler);
connector.getSessionConfig().setReadBufferSize(2048);

// try to connect to server!
try {
    System.out.println("Connecting to " + relayIP + ":" + port);
    ConnectFuture future = connector.connect(new InetSocketAddress(relayIP, port));
    future.addListener(new IoFutureListener<IoFuture>() {

        public void operationComplete(IoFuture future) {
            ConnectFuture connFuture = (ConnectFuture)future;
            if( connFuture.isConnected() ){
                UDPClient.setSession(future.getSession());

                Timer timer = new Timer("MyTimerTask", true);
                timer.scheduleAtFixedRate(new MyTimerTask(), 1000, 1000);  // My message is written here every 1000ms
            } else {
                log.error("Not connected...exiting");
            }
        }
    });
    future.awaitUninterruptibly();
} catch (RuntimeIoException e) {
    System.err.println("Failed to connect.");
    e.printStackTrace();
    System.exit(1);
} catch (IllegalArgumentException e) {
    System.err.println("Failed to connect. Illegal Argument! Terminating program!");
    e.printStackTrace();
    System.exit(1);
}

For any additional info please write in comments.

EDIT: Unfortunately I don't have access to that server any more, but problem was not solved back then. If there's anybody else who has the same problem and solved it, let us know.

1
What is the value of IDLE_PERIOD? Maybe, you close the connection when the idle status received? Could you put your IOHandler code? - Ricardo Cristian Ramirez
Which mina version are you using? - igreenfield
@Ricardo Cristian Ramirez IDLE_PERIOD is set to 10, there's no explicit connection closing and it works well with iOS devices, just not with java desktop client (either MINA or DatagramSocket implementation) and android client. - Jakub Turcovsky
@user467257 every second it sends data via UDPClient.getSession().write(). As you can see, this session is set above Timer initialization. The write is executed every second and message arrives to server OK, so the session is active and used every second of that minute. - Jakub Turcovsky
TIME_TO_LIVE is a part of the IP packet and has nothing to do with a connection. In fact, UDP is connectionless. The whole concept of a UDP connection is implemented in Mina. Something is in Mina is closing the IoSession. - Johnny V

1 Answers

1
votes

I did some research and found the link below. You may need to explicitly set the disconnect option to false, but there is also another option to reset the timeout option. A timeout of 30000 is 30 seconds, 60000 is 60 seconds, etc... These solutions are from MINA2. It was not clear if you were using that or an older version. From this you should be able to add the call that implements a specific set of options when you open the UDP port.

MINA2 Documentation