26

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.

Jakub Turcovsky
  • 1,955
  • 3
  • 25
  • 38
  • 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 Mar 09 '15 at 14:31
  • 1
    Which mina version are you using? – igreenfield Apr 28 '15 at 01:29
  • @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 Apr 28 '15 at 12:37
  • @igreen It's version 2.0.9 – Jakub Turcovsky Apr 28 '15 at 12:38
  • Still not solved btw! – Jakub Turcovsky Jun 08 '15 at 09:27
  • 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. – user467257 Jun 09 '15 at 07:53
  • 1
    @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 Jun 09 '15 at 11:52
  • 1
    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 Aug 07 '16 at 13:29
  • 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? – Alex Oct 04 '20 at 09:17

1 Answers1

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

Razelle
  • 56
  • 4