2013-10-06 15 views
5

Tomcat 8のJSR-356 WebSocketサポートを使用して、私が取り組んでいるアプリケーションを駆動しています。これまでは、すべてのメッセージが1つのスレッドで処理されるように見えました。私はこの背後にある理由を理解していますが、WebSocketがこのように実装されている理由を理解していますが、ExecutorServiceを使用して(メッセージにExecutorServiceを作成せずに)メッセージを処理する方法はありますか?Tomcat 8 JSR 356 WebSocketスレッディング

これは、実際のメッセージの標準的なスレッドベースの処理を可能にする一方で(1つまたは少数の)ネットワークセレクタスレッド(接続された多数のクライアントをサポートする)をスケーラビリティできるようにしますクライアントのために処理される)。

特にこれが変更されることはありません。

答えて

13

スレッドモデルは、使用しているコネクタによって異なります。スケーラビリティのために、NIO(デフォルト)またはAPR /ネイティブ(8.0.0-RC3現在のバグ)を使用します。 NIOは現時点では本当に唯一の選択肢です。まもなくAPR /ネイティブの問題を修正する必要があります(私はこの質問を見たときに作業していました)。

NIOはセレクタとスレッドプールを使用して受信メッセージを処理します。セレクタは、データが利用可能であることを検出すると、スレッドプールからスレッドを(executorを介して)処理します。この処理により、データが内部的にバッファリングされ、アプリケーションに部分的なメッセージが通知され、アプリケーションに完全なメッセージまたはこれらの組み合わせが通知されることがあります。アプリケーションへの通知は、着信データを処理する同じスレッドによって処理されます。

複数のクライアントから複数のメッセージが受信された場合、それらのメッセージを処理するために複数のスレッドがディスパッチされます。

JSR 356 APIには、アプリケーションがアプリケーションを実装せずに新しいメッセージを通知された場合に、ExecutorService経由でメッセージまたは部分的なメッセージを処理する機能があります。これは、メッセージ全体を処理するだけのアプリケーションでこれを実装するのは比較的簡単です。アプリケーションが部分的なメッセージを処理する場合、それはもっと難しくなります。

APR /ネイティブ(一度修正)はNIOと同じように動作します。 BIOは常にブロックIOを使用します(JSR356 APIがノンブロッキングを示す場合でも)。また、処理するデータを持つ接続されたクライアントごとに1つのスレッドではなく、接続されたクライアントごとに1つのスレッドが必要です。

+0

スレッドプールを使用して着信データを処理すると言っていますか?クライアントごとに最大1つのスレッドがありますか? –

+0

私がテストしていたときに、2番目のメッセージが最初に処理を完了するのを待っているように見えたので、私は尋ねます。しかし、私たちはどちらも同じセッションから送られてきました(たぶんそれが理由でした)。サイドノート:偉大な答え –

+3

クライアントごとにデータを処理するために割り当てるスレッドは複数ありません。クライアントが複数のメッセージを送信した場合、クライアントは同じスレッドによって順次処理されます。スレッドが最初のメッセージを終了すると、読み取るデータがさらにあることがわかります。もしあれば、それを読むでしょう。そうでない場合、ソケットはセレクタ/ポーラーにデータが到着するまで戻る。このようにデータを処理する必要があります。より多くのスレッドのスコープがある場合、メッセージ(または部分的なメッセージ)がアプリケーションに渡される準備ができたら、それは新しいスレッドで行うことができます(ただしそうではありません)。 –