2013-01-09 55 views
2

我們有大量的小請求HTTP服務,且大多隻要求一次(約70%)在netty中,如何捕獲所有channelClosed事件?

因此,如果我們保持通道打開,當請求,很快就會有渠道住了很多在內存中無所事事。

目前我們所做的是註冊一個IdleStateHandler和一個IdleStateAwareChannelHandler, ,這樣任何5秒內沒有任何活動的頻道將被關閉。

這似乎工作,並打開渠道的大小是穩定的。

但是我們有另外一個問題:

對於每個打開的通道,我們已經定製與之相關聯的ServerConnection對象, 存儲與當前頻道的一些有用的信息。我們將這些ServerConnection保存在一個名爲connectionMap的全局映射中,其中的關鍵是通道。

每次調用messageReceived時,我們檢查通道是否已經在connectionMap中,如果沒有,就創建一個新的ServerConnection。

每次檢測到channelClosed/exceptionCaught事件時,我們會調用connectionMap.remove將其刪除。

而我們在調用IdleStateHandler時手動從地圖上移除。

但是一些ServerConnections不會被刪除,而其Channel的狀態實際上是關閉的。

我們錯過了什麼嗎?有一個頻道關閉的地方,但我們忘了趕上事件?

+0

我正在嘗試實施類似於您的解決方案。你有沒有實現你自己的解碼器?當客戶端關閉telnet時,我的服務器首先獲取messageReceived然後channelClosed,但是我期望的只是頻道關閉。所以據我瞭解,斷開連接也會觸發messageReceived事件。但messageReceived事件中的消息沒有意義,因爲客戶端已關閉連接。爲了解決這個問題,我想如果我可以實現一個解碼器比我可以正確處理messageReceived中的通道關閉嗎?你怎麼看待這件事? –

回答

4

當頻道關閉時,您可以通過使用ChannelFutureListener界面並在頻道近期註冊時收到通知。

class MyClass implements ChannelFutureListener 
{ 
    // Whatever stuff this class also does 
    // ... 

    public void operationComplete(ChannelFuture future) throws Exception 
    { 
     System.out.println("This channel closed! " + 
          future.getChannel().getId().toString()); 
    } 

} 

然後爲你的頻道做什麼...

channel.getCloseFuture().addListener(instanceOfMyClass); 

當通道關閉,您ChannelFutureListener得到通知。

注意這是Netty 3.x. Netty 4.x在一些你不需要調整的東西上改變了方法名(他們從getters中刪除了前綴get)。

+0

這是ClosesFuture()保證被稱爲所有通道關閉嗎? –