2012-04-03 137 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