2011-02-01 7 views
4

ステートフルなマルチクライアントサーバーアプリケーションを実装しようとしており、ネットワーク/スレッド設計に関するいくつかの質問があります。私が現在直面している問題は、通信レイヤーとロジックレイヤーの間でメッセージを交換する方法です。Javaマルチスレッドステートフルサーバーネットワーキング設計

サーバーは複数のクライアントを処理します。複数のクライアントはそれぞれ複数の「チャネル」でアクティブになり、各チャネルには複数のステージがあり、複数のクライアントが動作します。それを複数の部屋を持つチャットプログラムと似たようなものと考えてください。

私はすでにサーバー側でメッセージの受信を実装しています。各クライアントには、データをブロッキングで読み取ってメッセージにデコードする独自のスレッドがあります。今どのように進める?私の意見では、各チャンネルには、その状態を簡単に維持するためのスレッドが必要です。私はBlockingQueueを使用して、受信したメッセージをチャネルスレッドと交換することができます。チャネルスレッドは、そのキュー上の新しいメッセージをブロックして待機しています。

しかし、どのようにクライアントにメッセージを送信するのですか?チャネルのロジックはメッセージを処理し、クライアントの1つ/ some/allに送信されるメッセージを生成します。ソケットに直接書き込むためにチャネルスレッドを使用するのは安全ですか?または、別のBlockingQueueを使用してメッセージをクライアントハンドラスレッドに送信する必要がありますか?しかし、ソケットを読み取るのを待っているので、それを目覚めさせる方法は?または、クライアントごとに個別の送信スレッドを使用するか、別の送信ソケットを使用する必要がありますか?

ところで、私はネットワーキング層に既存のライブラリを使うことができますが、普通のソケットでは最初からやりたいと思っています。

+0

処理が安価でメッセージ単位であれば、私はマルチスレッド化することはできません。代わりに原子炉の使用を検討します。各クライアントおよび/またはチャネルに状態があるということは、スレッドを使用する必要があるということを意味しません。 – sinelaw

+0

@sinelawあなたはNIOを参照していると思います。私はこの記事を読んでhttp://paultyma.blogspot.com/2008/03/writing-java-multithreaded-servers.html NIO/IOを比較しているので、接続ごとに1つのスレッドを使用することにしました。 )。しかし、チャンネルのために、別のアプローチを選択することができます...実際の質問は同じです –

答えて

1

ソケットをラップする通信オブジェクトにメッセージの送信方法を設定します。一度に1つのスレッドしか呼び出せないように、このメソッドを同期させます。次に、このメソッドを呼び出すスレッドの数に違いはありません。各メッセージは一度に1つずつ送信されます。また、読み込みをブロックしているスレッドを妨害する必要もありません。この送信メソッドは、スレッドが送信している間に他のスレッドがブロックされることを心配する必要がない、すばやい操作です。

チャネルが接続された各クライアントの通信オブジェクトへの参照を持っている限り、メッセージは送信され、心配はありません。

問題が発生した場合は、送信メッセージを変更して、送信するオブジェクトをエンキューすることができます。次に、キュー上でブロックして内容をソケットに書き込む特定の送信スレッドを持つことができます。しかし、私の経験からは、これは必要ではありません。

+0

それは私が "直接ソケットに書き込む"とは、悪いforumlationだった意味です。しかし、「incommingメッセージを読む」ためのスレッドと「メッセージを処理して複数のクライアントに応答を書く」という別のスレッドを持つことは私にとっては奇妙なことです。しかし、多分これはスレッドタスクデカップリングのためのちょっとした趣味かもしれません... –

+0

あなたのチャンネルスレッドはメッセージを処理し、複数のコミュニケーションオブジェクトにレスポンスを書いていませんか?私はそのスレッドとあなたのコミュニケーション・オブジェクトの間に何が必要なのか理解できません。効果的に、そのスレッドは、通信オブジェクトを介して直接ソケットのすべてに書き込むことになります。 –

-1

イベントメカニズムについてはどうですか?要求を処理する準備が整っていて、利用可能なクライアント用のデータがある場合は、クライアントソケットハンドラスレッド用のイベントを送信するだけです。クライアントからの送信が終了したため、正常に返信することができます。