2013-10-06 26 views
5

我使用Tomcat中8 JSR-356 WebSocket的支持,從而推動我工作的應用程序。到目前爲止,它看起來像所有的消息都在一個線程中處理。雖然我明白這背後的原因 - 以及爲什麼websockets以這種方式實現,是否有任何方法可以使用ExecutorService來處理進來的消息(而不是在我的代碼中創建ExecutorService)?Tomcat的8 JSR 356的WebSocket線程

這將允許具有1個(或僅少數)網絡選擇器線程(以支持大量連接的客戶端)的可擴展性,同時允許對實際消息進行標準的基於線程的處理(當消息需要時爲客戶處理)。

我看不出有什麼特別,將允許這種改變。

回答

13

的線程模型取決於你所使用的連接器而異。對於想要使用NIO(缺省值)或APR/native(從8.0.0-RC3開始)的可擴展性。 NIO是目前唯一的選擇。 APR /原生問題應該很快修復(當我看到這個問題時,我正在研究這個問題)。

NIO使用選擇和線程池來處理接收到的消息。當選擇器檢測到數據可用時,它將套接字傳遞給線程池中的線程(通過執行程序)以進行處理。該處理可能導致數據在內部被緩衝,應用程序被通知部分消息,應用程序被通知完整消息或這些消息的組合。對應用程序的通知由處理傳入數據的相同線程處理。

如果從多個客戶端收到多封郵件,然後多線程將被分派到處理這些信息。

JSR 356 API中沒有任何功能允許應用程序選擇通過ExecutorService處理的消息或部分消息,其中一個應用程序在沒有應用程序執行的情況下收到新消息通知。對於僅處理整個消息來執行此操作的應用程序來說,這應該相對簡單。如果應用程序處理部分消息,那麼它會更困難。

APR /天然的(一旦固定)將表現方式與NIO相同。 BIO始終使用阻塞IO(即使在JSR356 API指示非阻塞的情況下),並且每個連接的客戶端也需要一個線程,而不是每個連接的客戶端需要一個線程來處理數據。

+0

好吧,你是說它確實使用線程池來處理傳入數據?每個客戶端是否有最多一個線程? –

+0

我問,因爲當我測試時,它看起來像第二條消息正在等待第一個完成處理。但是,我們都是從同一個會話發出的(也許這就是爲什麼)。附註:很好的答案 –

+3

分配給每個客戶端處理數據的線程不會超過一個。如果一個客戶端發送多個消息,那麼它們將按順序處理 - 可能是由相同的線程處理。當線程完成第一條消息時,它會查看是否有更多數據要讀取。如果有,它會讀取它。如果沒有,套接字將返回到選擇器/輪詢器,直到更多數據到達。數據必須以這種方式處理。在有更多線程的地方,一旦消息(或部分消息)準備好傳遞給應用程序,就可以在新線程中完成(但不是)。 –