2017-04-26 11 views
0

私はチャットのようなサービスを作成しています。jettyの他のスレッドからのwebsocketメッセージのブロードキャスト

ユーザがページを開くと、websocketエンドポイントに接続し、着信メッセージを待ちます。

サーバー側では、jettyを使用するJavaアプリケーションが接続を待機しています。ユーザーがメッセージを送信するたびに、メッセージはすべてのクライアントにブロードキャストされます。別のスレッドから時々送信されるシステムメッセージもあります。

問題は、このソリューションのスレッドの安全性が本当に心配です。私が理解するところでは、jettyはxワーカースレッドでスレッドプールを使用するので、複数の接続が複数のスレッドによって処理される可能性があります。私のシステムメッセージサービスは、jettyスレッドプールの外でも、別のスレッドでも実行されます。

ブロードキャスト機能は、ほとんどの場合、この(汎用関数名)のように見えるように起こっている:

for(Connection connection : server.getWebSocketConnections()) 
    connection.sendMessage(message); 

それを呼び出したスレッドに応じて:

  1. getWebSocketConnectionsによって返されたコレクションが中に変更することができます繰り返し。
  2. 接続がすでにクローズさ/のsendMessage
  3. を行うとき

いくつかの内部バッファの競合状態などがある場合があります配置された/削除されたことがありそこで質問です:

安全にメッセージをブロードキャストする方法桟橋を使用して外部スレッドからすべてのWebSocket接続を開きますか?

答えて

1

面白いことに、私は過去数週間同じことに取り組んできました。 あなたが言ったように、放送はスレッドセーフである必要があります。 これは、私はそれを行う方法です。

public void broadcast(String message, AnnotatedSocket excludedClient) { 
    logger.debug("Sending to all clients:{} ", message); 
    synchronized (clients) { 
     for (AnnotatedSocket as : clients) { 
      if (!as.equals(excludedClient) && as.getSession().isOpen()) { 
       try { 
        as.getSession().getRemote().sendStringByFuture(message); 
       } catch (Exception e) { 
        logger.error("Error{} when broadcasting to {} {} ",e,as.getId(),as.getAddress());          
       } 
      } 
     } 
    } 
} 

クライアントは、サーバーが所有する同期リストであり、そして放送が必要とされるたびに、すべてのソケットで使用されているが、それは私が理解したものから、スレッドセーフに保たれています。 それはうまくいくかもしれませんが、私はこれをかなり新しくしています。 興味がある場合はマルチキャストも実装しました。 私の進め方についてさらに詳しい情報が必要な場合は、私に教えてください。

乾杯。

関連する問題