我正在实现一个 serlvet,它使用AsyncContext可以将消息异步发送回客户端。其他 servlet 需要能够为客户端排队消息,然后当浏览器通过 AJAX 请求消息时将这些消息提供给客户端。
我当前的实现使用静态计时器:
private static Timer messageSender = new Timer("MessageSerlvetSender", true);
它被创建为一个守护线程,因此它不会使 servlet 容器的线程保持活动的时间超过应有的时间。其他 servlet 通过以下方式排队消息:
public static void write(HttpServletRequest req, MessageType type, String message) {
try {
synchronized (messageSender) {
messageSender.schedule(new MessageTask(hashSession(req), type, message), MSG_DELAY_MS, MSG_TIMEOUT_MS);
}
} catch (IllegalStateException ex) {
// Timer daemon thread has been canceled
messageSender = new Timer("MessageSerlvetSender", true);
write(req, type, message);
}
}
MessageTask
是一个可运行对象,它抓取AsyncContext
已添加到哈希映射(使用会话 ID)、写入消息、完成上下文并在成功时取消任务。
这是线程安全的,并且允许在守护线程死亡时重新启动计时器。这个实现试图不假设任何状态来遵守 servlet 的 API,但它感觉......很脏。在这种情况下,最佳做法是什么?如何利用 HTTP 会话属性?