2012-04-03 100 views
2

我一直在用Apache Mina开发我的第一个基于TCP/Socket的应用程序,它看起来不错并且容易做事。我只想在这里问一个关于米娜的问题。Apache Mina空闲监视器

服务器并处5秒的空闲时间将终止套接字连接,所以我们要定期发送心跳(回声消息/存活),以确保连接是活的。一系列保活机制。

有,我们只是每5秒钟,然后盲目地发送回声/心跳消息的一种方式。我在想,如果我正在发送我的商业信息,并且没有空闲时间,即5秒钟,应该有智能/智能的方式“空闲监视器”,我不应该发出心跳信息。如果整个连接空闲,心跳消息将被发送,这样我们可以节省带宽并快速读取在套接字上写入的数据。

在此先感谢,对所有谁喜欢这个概念,并尽量给予解决。

回答

4

您可以通过使用Keep Alive Filter(已经在米娜存在)实现它。

或者,您可以通过将客户端的会话空闲超时设置为比服务器的空闲超时小一点来实现发送回声/心跳的更智能的方式。例如:

对于服务器端

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

和客户端这将是

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

现在,如果没有沟通的可以说3秒,一个sessionIdle将被triggred客户端(并且它不会在服务器端触发,因为超时时间为5秒),您可以发送回显。这将保持会话活着。回声将仅在会话空闲时发送。

注意:我假设在会话空闲时,会话正在服务器端关闭。如果有其他方法,您需要切换会话空闲超时的值(例如,服务器为3秒,客户端为5秒),回显将从服务器发送。

+0

谢谢你Umer。我正在寻找这种情况下的最佳解决方案。我概述了KeepAlive过滤器,在IoHandler和自定义线程/定时器上闲置时间以发送回显消息。现在我认为,IoHandler的闲置超时时间看起来最好。 – 2012-04-06 10:15:32

+0

@FaisalBasra所以,你的意思是你会选择在这个答案中的解决方案?不用担心,我很高兴它为你工作:) – 2012-04-06 10:22:52

+0

是的。我们的第三方服务器强制每30秒发送一次echo/heartbeat消息,我认为是 NioSocketConnector.getSessionConfig()。setIdleTime(IdleStatus.BOTH_IDLE,3);然后在处理程序的“@Override \t public void sessionIdle(IoSession session,IdleStatus status)”将很好。感谢您的想法和理念。万分感激。 – 2012-04-09 05:49:35

1

我不知道我完全理解你的问题,但你可以在IoHandlerAdapter的重写sessionIdle方法发送心跳。您不必仅仅因为服务器端的Mina调用Idle就关闭会话。至于在没有这种心跳通信的情况下维持服务器和客户端之间的活动连接的更智能的方式,我从来没有听说过。

这里是微软如何处理自己的心跳在ActiveSync一个有趣的阅读。在我的客户端/服务器应用程序中使用mina时,我个人使用了这种方法。希望这可以帮助你一些。

+0

如果什么,我们使用定时器/线程其中发送定期回声/心跳消息? – 2012-04-05 08:47:12

+0

确定你可以创建一个带有定时器的线程来发送心跳ping。我试图做的一点是,客户端和服务器线程暂时闲置一段时间并没有什么问题,它可以节省服务器和客户端上的带宽资源,因为它包含有关与客户端或服务器的会话的所有信息,但它不积极沟通。因此,您可以轻松地将自己的计时器放在sessionIdle方法中,并尝试检测心跳,如果失败,则关闭会话。 – shibbybird 2012-04-05 14:16:17

+0

shibbybird,谢谢。 但我们正在与第三方服务器集成,并且他们施加了这种限制,因此我们必须保持连接明确存在,否则第三方服务器将断开与我们的连接。 – 2012-04-06 10:12:30

0

(我希望我理解正确的问题)

我遇到了麻烦,让我的会议还活着,这个问题就在谷歌的搜索结果,因此我希望别人会发现它很有用:

@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(); 
    } 

(来源:https://issues.apache.org/jira/browse/SSHD-185