2015-10-05 12 views
12

私はPlay2とJavaでWebSocketベースのソリューションを実装しようとしています。現在、私は同時実行管理にActor Modelを使用していません。代わりに、ちょうどhandling the WebSockets using callbacksです。Java - Play2 WebSocket実装にアクターが必要ですか?

問題は、サーバーが複数のクライアントにメッセージを「ブロードキャスト」できないことです。たとえば、クライアントを介してアクションがトリガーされた後に、すべてのアクティブなブラウザー・セッションが単純な通知を受け取る必要があります。代わりに、私はちょうど単一のクライアントセッションのためにこれをシミュレートすることができます。実際には、Ajaxの通常のリクエスト/応答のシナリオとして機能します。

私の推測は、Play2のWebSocketsソリューションです&単純なコールバックを持つJavaは、接続されたすべてのクライアントブラウザにメッセージをブロードキャストできません。

コールバックサーバコードで

public static WebSocket<String> heartUpdate() { 
     return new WebSocket<String>() { 
      public void onReady(final WebSocket.In<String> in, 
        WebSocket.Out<String> out) { 
       in.onMessage(new Callback<String>() { 
        @Override 
        public void invoke(String event) throws Throwable { 
         Product product = Product.find.byId(Long.decode(event)); 
         // Other business stuff 
         out.write(entity.id + " " + decimalValue); 
        } 
       }); 
       in.onClose(new Callback0() { 
        @Override 
        public void invoke() throws Throwable { 

        } 
       }); 
       out.write(DELIM_USERID_REP); 
      } 
     }; 
    } 

ルートエントリ

GET /repsocket controllers.Application.heartUpdate 

クライアント側

<script> 
    // Onto the WebSockets now 
    var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket; 
    var socket = new WS("@routes.Application.heartUpdate.webSocketURL(request)"); 

    var receiveEvent = function(event) { 
     alert(event.data); 
     // Notification badge visible with a common text 
     $('#notify').text(event.data); 
     $('#notify').addClass('visible'); 
    } 
     $('#heart').click(function(e) { 
      e.preventDefault(); 
      socket.send(@product.id); 
     }); 
    socket.onmessage = receiveEvent; 
    </script> 

上記の場合、アクションをトリガーするクライアントは、サーバーからメッセージを正常に受信するものであり、他のブラウザセッションは受信しません。

Javaの&を持つPlay2に対応したドキュメントを見つけることができませんでした。接続されているアクティブなクライアントとの一貫した通信を維持するためにアクターを強制的に使用することを示唆するWebSocket。

質問:Play2とJavaのWebSocketをアクターモデルで実装して、アクティブなクライアントセッションすべてにメッセージをブロードキャストする必要がありますか?

編集: 以下のスクリーンショットは、2つの有効なユーザー資格情報を使用してログインしている2つのブラウザの状態を示しています。

理想的には、サーバーからのWebSocketsの応答は、両方のブラウザで同じ通知バッジを作成する必要があります。

enter image description here

+0

あなたにはどんなエラーがありますか? –

+0

@nikponエラーはありません。サーバーからのメッセージは、1つのブラウザセッションに反映されているだけで、他の接続されているクライアントセッションではリクエストがトリガーされていませんでした。 – PopoFibo

+0

ブラウザのセッションはどのように取得しましたか? –

答えて

5

は、あなたが投稿したコードを見てみると、問題はあなたが後でメッセージをブロードキャストすることができますので、あなたは、各接続への参照を保存していないということであるようです。このような何か:

// Just an example: does not deal with concurrency problems 
private static final Set<WebSocket.Out<String>> SOCKETS = new HashSet<>(); 

public static WebSocket<String> heartUpdate() { 
    return new WebSocket<String>() { 
     public void onReady(final WebSocket.In<String> in, 
        final WebSocket.Out<String> out) { 
      SOCKETS.add(out); 
      in.onMessage(new Callback<String>() { 
       @Override 
       public void invoke(String event) throws Throwable { 
        for(WebSocket.Out<String> s: SOCKETS) { 
         s.write("SOME MESSAGE");  
        } 
       } 
      }); 
      in.onClose(new Callback0() { 
       @Override 
       public void invoke() throws Throwable { 
        SOCKETS.remove(out); 
       } 
      }); 
     } 
    }; 
} 

また、この問題をモデル化するために俳優を使用することができます接続を追跡し、新しいソケット接続/クローズに対処する責任役者を持ちます。

あなたがAkkaを使用したい場合は、some activator templatesがあります。

+0

これは実際にはループの中で実際に元の問題と同じ動作をしました。おそらくもっと基本的なものが欠けているかもしれません。 – PopoFibo

+0

私はそれをすべて間違ってテストしていました。それは実際に動作します、ありがとう。私はあなたの答えにいくつかの牽引のためのオープンな恩恵を受け入れてこの問題を残します。 – PopoFibo

関連する問題