Java 每个客户端的 EE AsyncContext
Java EE AsyncContext Per Client
我正在为一个较长的 运行 进程使用异步 servlet,并在客户端实现了长轮询,因此它可以显示进度并在完成时通知客户端。我实现了一个通知程序 servlet,它通过自定义 EventNotify class 手动插入会话 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);
这是一个解决方案。
摆脱 @Singleton 不起作用,因为 AsyncContexts 根本停止了 "connecting"。
有效的是保持单例并摆脱队列对等体。相反,维护一个哈希图:
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 存在负载平衡器问题。
我正在为一个较长的 运行 进程使用异步 servlet,并在客户端实现了长轮询,因此它可以显示进度并在完成时通知客户端。我实现了一个通知程序 servlet,它通过自定义 EventNotify class 手动插入会话 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);
这是一个解决方案。
摆脱 @Singleton 不起作用,因为 AsyncContexts 根本停止了 "connecting"。
有效的是保持单例并摆脱队列对等体。相反,维护一个哈希图:
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 存在负载平衡器问题。