2

I have been developing my first TCP/Socket based application with Apache Mina, it looks great and easy to do things. I just want to ask a question here about Mina.

The server impose an idle time of 5 second will terminate the socket connection, so we have to send periodic heartbeat (echo message / keepalive) to make sure connection is alive. Sort of keepalive mechanism.

There's one way that we send blindly echo/heartbeat message just before every 5 seconds. I am thinking, there should be smart/intelligent way "Idle Monitor" if I am sending my business message and do not come to idle time i.e. 5 second, I should not issue heartbeat message. Heartbeat message will be sent if whole connection is idle, so that we save bandwidth and fast reading & writing on socket.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Faisal Basra
  • 1,624
  • 4
  • 25
  • 40

3 Answers3

4

You can achieve it by using Keep Alive Filter (already present in mina).

Alternatively, you can achieve a smarter way of sending echo/heart beat by setting session idle timeout of client a bit smaller than idle timeout of server. For example:

For server side

NioSocketAcceptor.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 5);

and for client side it would be

NioSocketConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3);

Now, if there is no communication for lets say 3 seconds, a sessionIdle will be triggred at the client side ( and it will not be triggered at server side as timeout there is 5 seconds) and you can send an echo. This will keep the session alive. The echo will be sent only if the session is idle.

Note: I am assuming that at session idle, session is being closed at the server side. If it is other way around you will need to switch values of session idle timeout(e.g. 3 seconds for server and 5 seconds for client) and echo will be sent from server.

Umer Hayat
  • 1,993
  • 5
  • 31
  • 58
  • Thank You Umer. I was looking out the best solution for this scenario. I outlined, KeepAlive Filter, idle timout at IoHandler & custom thread/timer for sending echo message. Now I think, IoHandler's idle timeout looking the best. – Faisal Basra Apr 06 '12 at 10:15
  • @FaisalBasra So, you mean you are going for alternative solution purposed in this answer?. No worries, I am glad it worked for you :) – Umer Hayat Apr 06 '12 at 10:22
  • Yes. Our third party server forces to send echo/heartbeat message every 30 second, & I think NioSocketConnector.getSessionConfig().setIdleTime(IdleStatus.BOTH_IDLE, 3); and then in handler's "@Override public void sessionIdle(IoSession session, IdleStatus status) " will work great. Thanks for your idea & concept. Really appreciate. – Faisal Basra Apr 09 '12 at 05:49
2

(I hope I'm understanding the question correctly)

I was having trouble keeping my session alive and this question came up on Google search results so I'm hoping someone else will find it useful:

    @Test
    public void testClientWithHeartBeat() throws Exception {
        SshClient client = SshClient.setUpDefaultClient();
        client.getProperties().put(ClientFactoryManager.HEARTBEAT_INTERVAL, "500");
        client.start();
        ClientSession session = client.connect("localhost", port).await().getSession();
        session.authPassword("smx", "smx").await().isSuccess();
        ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);

        int state = channel.waitFor(ClientChannel.CLOSED, 2000);
        assertTrue((state & ClientChannel.CLOSED) == 0);

        channel.close(false);
        client.stop();
    }

(Source: https://issues.apache.org/jira/browse/SSHD-185)

In newer versions (e.g. version 2.8.0), enabling heartbeats changed to CoreModuleProperties.HEARTBEAT_INTERVAL.set(client, Duration.ofMillis(500));

Gili
  • 86,244
  • 97
  • 390
  • 689
Sridhar Sarnobat
  • 25,183
  • 12
  • 93
  • 106
1

I'm not sure I totally understand your question, but you can send a heartbeat in an overridden sessionIdle method of the IoHandlerAdapter. You don't need to necessarily close a session just because Mina on the server side calls Idle. As far as a more intelligent way of maintaining an active connection between and Server and Client without this type of heartbeat communication I have never heard of one.

Here is an interesting read of how microsoft handles their heartbeat in ActiveSync. I personally used this methodology when using mina in my client/server application. Hope this helps you some.

shibbybird
  • 1,245
  • 13
  • 28
  • What if, we used Timer/Thread which send periodic echo/heartbeat message? – Faisal Basra Apr 05 '12 at 08:47
  • Sure you can create a thread with a timer on it that sends a heartbeat ping. The point that I was trying to make is that there is nothing wrong with a client and server thread staying idle for a while it saves bandwidth resources on both the server and client because it holds all the information about the session with the client or server but it not actively communicating. So you can easily put your own timer within the sessionIdle method and try a heartbeat ping, and if it fails then close the session. – shibbybird Apr 05 '12 at 14:16
  • shibbybird, Thanks. But we are integrating with third party server, and they impose such restrictions so we have to keep the connection alive explicitly otherwise third party server will disconnect us. – Faisal Basra Apr 06 '12 at 10:12