2017-01-14 4 views
2

Я использую асинхронные сервлеты для долгого процесса и реализовал длительный опрос на стороне клиента, чтобы он мог отображать прогресс и уведомлять клиента по завершении. У меня есть реализованный сервлет-уведомитель, который вручную сортирует, какие клиенты получают какое сообщение, вручную вставляя идентификатор сеанса через собственный класс EventNotify. Если 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

Возможно, веб-сайт, возможно, лучший выбор? – maress

ответ

0

Вот решение. Избавление от @Singleton не работает, потому что AsyncContexts вообще перестали подключаться.
Что делает работа по поддержанию синглтона и избавлению от сверстников очереди. Вместо этого, поддерживать HashMap:

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

sessionacmap.put(sessid, ac); 

вместо петли аналоги:

for (AsyncContext ac : peers) { 

Толкай только asynccontext и поступать в соответствии, что:

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

В результате только клиент запрашивающий конкретная работа будет уведомляться только о событиях, связанных с этой работой. Не шумно и хорошо масштабировать. Websockets также должны работать, но в нашем конкретном случае у нас есть проблема балансировки нагрузки с веб-сайтами.

Смежные вопросы