我正在为长时间运行的进程使用异步servlet,并在客户端实现了长轮询,因此它可以显示进度并在完成时通知客户端。我实现了一个通知程序servlet,通过自定义EventNotify类手动插入会话ID,手动排序哪些客户端获取了哪些消息。如果getEventId()与eventid不同,我们将“IGNORE”发送到客户端,客户端手动忽略该消息。 notifyPeers自动向所有客户端发送通知。如果许多长时间运行的作业正在运行,这可能会变得非常嘈杂。有没有办法让notifyPeers只发送通知给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 :(得分:0)
这是一个解决方案。 摆脱@Singleton是行不通的,因为AsyncContexts已停止&#34;连接&#34;一点都没 什么工作是保持单身和摆脱队列同行。相反,维护一个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也应该工作,但在我们的特定情况下,我们遇到了websockets的负载平衡器问题。