Apache MINA server closes active UDP "session" after 60s
Asked Answered
B

2

27

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.

Boehmenist answered 28/1, 2015 at 8:8 Comment(9)
What is the value of IDLE_PERIOD? Maybe, you close the connection when the idle status received? Could you put your IOHandler code?Shutdown
Which mina version are you using?Hodgepodge
@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.Boehmenist
@igreen It's version 2.0.9Boehmenist
Still not solved btw!Boehmenist
What is your MyTimerTask doing ? I more or less copied your code and unless the MyTimerTask does something like a iosession.write (with a protocol encoder added to the chain) i also get session closed after 60s, otherwise it stays open.Maintenance
@Maintenance 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.Boehmenist
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.Sesqui
We have the same behaviour (sending messages from a unix system to a windows system). The same jar-file works on "Windows-To-Windows". Its quite crazy. Did somebody find a solution for this?Gwendolyngweneth
A
1

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

Aerometry answered 11/7, 2015 at 17:20 Comment(0)
C
0

The solution is to create a ExpiringSessionRecycler like this:

NioDatagramAcceptor acceptor = new NioDatagramAcceptor();
ExpiringSessionRecycler sessionRecycler = new ExpiringSessionRecycler(600); //600=10 minutes        
acceptor.setSessionRecycler(sessionRecycler);
Charioteer answered 6/1 at 2:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.