2012-03-14 55 views
1

我實現我自己的幀解碼器來解析根據我們的協議,通過(使用NioDatagramChannelFactory和ConnectionlessBootstrap)UDP套接字接收的字節數「channelInterestChanged」事件。 爲了跟蹤接收消息時服務器中發生的事情,我在解碼器的每個回調方法中添加了跟蹤日誌。不知道明白爲什麼我的服務器接收的幀解碼器

似乎對於服務器接收幾乎所有的消息時,我們可以看到,該事件「channelInterestChanged」在方法channelInterestChanged()接收到的兩倍。事件的值首先是0(OP_NONE),然後是1(OP_READ)。

我讀到這個文件,但我仍然不知道明白爲什麼我收到這樣的事件。我第一通,這是因爲接收緩衝器(或選擇器隊列)是滿的,但是服務器接收到該事件的相同的次數它接收「的messageReceived」事件(解碼之前()方法被調用)和所有的消息/幀如預期的那樣正確解碼。當消息丟失時,我根本沒有看到任何事件。在這種情況下,可能是因爲數據報套接字的接收緩衝區已滿。但即使我增加了這個接收緩衝區,我仍然會看到這些事件並錯過消息。

所以,我很奇怪,爲什麼對於每個接收郵件時,服務器還接收兩個「channelInterestChanged」,一個與OP_NONE值和一個與OP_READ值。請注意,在通道管道中,在我的幀解碼器之後,還有一個ExecutionHandler和另一個特定於業務的處理程序(它將JMS消息發送到ActiveMQ實例)。

任何想法或解釋給我嗎?

謝謝。

+0

有興趣知道的是我自己。爲什麼不嘗試連接netty源並調試它,Netty有一個'fireEvent'方法,它將這些事件上行/下行發送到通道中。也許它來自java ** NIO選擇器**本身,而Netty只是將它傳輸到幀解碼器。 – Abe 2012-03-16 02:38:46

回答

0

當DownStreamChannelStateEvent從處理器發射(如呼叫channel.setReadable()channel.setWriteable()),該事件將改變NioDatagramWorker通道的NIO選擇鍵的興趣選擇,後來,一個UpstreamChannelStateEvent將有改變的選項解僱(即OP_READOP_NONE

你的幀解碼器處理程序接收UpstreamChannelStateEvents因爲,在管道的一些其他處理程序改變通道的閱讀興趣選項(調用channel.setReadable/setWriteable的目的,節流讀/寫,以避免在應用堵塞,OutOfMemoryError )。

如果您的流水線中有任何MemoryAwareThreadPoolExecutor(它監視所用通道內存的大小),它可能會在任何時候通過調用channel.setReadable()來暫停或恢復讀取,如果通道接收消息太快。您可能必須使用最佳的maxChannelMemorySize,maxTotalMemorySize配置MATPE實例,或者通過將其設置爲0來禁用它。

+0

非常感謝您對這些非常清晰的解釋!是的,我的管道中有一個MATPE,並且是有爲內存大小設置的特定值。在我將這些參數設置爲零後,我有效地注意到事件停止被觸發。但直到現在,我真的不確定明白爲什麼,究竟是如何在發動機罩下工作的! – The4Summers 2012-03-18 13:43:49

相關問題