2017-01-14 4 views
2

私は長時間実行するプロセスに非同期サーブレットを使用しており、クライアント側で長いポーリングを実装しているため、進行状況を表示して完了時にクライアントに通知できます。私はNotifierサーブレットを実装していて、カスタムEventNotifyクラスを介して手動でセッションIDを挿入することによってどのクライアントがどのメッセージを受け取るかを手動でソートします。 getEventId()がeventidと同じでない場合、クライアントに "IGNORE"を送信し、クライアントはメッセージを手動で無視します。 notifyPeersは自動的に通知をすべてのクライアントに送信します。長時間実行されているジョブがたくさん実行されている場合、これは本当に騒々しいことになります。 notifyPeersに、AsyncContextが登録されているクライアントだけに通知を送信する方法がありますか? ありがとうございます!Java EE AsyncContextクライアントごと

@Singleton 
public class Notifier { 
    private final Queue<AsyncContext> peers = new ConcurrentLinkedQueue(); 
    private final HashMap<AsyncContext, String> acsessionmap = new HashMap<AsyncContext, String>(); 

    public void notifyPeers(@Observes EventNotify evn) { 
     for (AsyncContext ac : peers) { 
      try { 
       String aceventid = acsessionmap.get(ac); 
       final ServletOutputStream os = ac.getResponse().getOutputStream(); 
       if (Util.equals(aceventid, evn.getSessd())) { 
        os.println(evn.getSessid() + ": " + evn.getMessage()); 
       } else { 
        os.println("IGNORE"); 
       } 
       ac.complete(); 
      } catch (IOException ex) { 
      } finally { 
       peers.remove(ac); 
      } 
     } 
    } 

public void addAsyncContext(final AsyncContext ac, String sessid) 
    ... 
    acsessionmap.put(ac,sessid); 
    peers.add(ac); 
+0

Websocketはおそらくここで最善の策ですか? – maress

答えて

0

ここに解決策があります。 AsyncContextが「接続中」を停止したため、@ Singletonを取り除くことはできません。
シングルトンを維持してキューピアを排除する作業は何ですか?結果は要求して唯一のクライアントである

AsyncContext ac = sessionacmap.get(evn.getEventid()); 
    if (ac==null) return; 
    try { 
     final ServletOutputStream os = ac.getResponse().getOutputStream(); 
    .... 

:その時に

for (AsyncContext ac : peers) { 

プルのみasynccontextと行為:代わりに、ピアループの

private final HashMap<String, AsyncContext> sessionacmap = new HashMap<String, AsyncContext>(); 

sessionacmap.put(sessid, ac); 

:代わりに、HashMapを維持特定のジョブは、そのジョブに関連するイベントのみに通知されます。騒々しくないし、うまくスケールする必要があります。 WebSocketもうまくいくはずですが、私たちは特定のケースではWebSocketにロードバランサーの問題があります。

関連する問題