我开始尝试 Comet 在服务器端使用 JMS 创建通知系统。
我需要一个 Web 服务向通知 CometHandler 的 servlet 发送异步消息。
我开始使用 Glassfish 的计数器示例(http://docs.oracle.com/cd/E18930_01/html/821-2418/ggrgt.html#ggrgr),但它似乎创建了很多处理程序。
问题(我认为)是彗星处理程序是在每个请求中创建的
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
CounterHandler handler = new CounterHandler();
handler.attach(res); //here the response of this request is attached to handler
CometEngine engine = CometEngine.getEngine();
CometContext context = engine.getCometContext(contextPath);
context.addCometHandler(handler);
}
然后在 CometHandler onEvent 中,处理程序将响应发送给客户端,然后自行恢复
public void onEvent(CometEvent event) throws IOException {
if (CometEvent.NOTIFY == event.getType()) {
response.getWriter().write("something") //response is the attached one
// commented out the resume if it is Http Streaming
event.getCometContext().resumeCometHandler(this);
}
}
在 HTML 页面中,我使用 JQuery 来做一个这样的 longPoll
function poll() {
var url = pollUrl;
$.getJSON(
url,
function(data) {
updateAnswer(data);//do things with data
poll();
}
);
}
因此,每个 getJSON,都会创建一个新的 CometHandler,而之前的一个会被“遗忘”。
问题是:有更好的方法来做到这一点吗?
如果我使用的下一个是另一个不同的,为什么我需要恢复处理程序?
谢谢你的帮助!
-- 编辑 --
我尝试将 cometHandler 放在 HttpSession 属性中,但问题仍然存在,因为我需要使用 addCometHandler(handler) 因为正如 javadoc 所说:
Add a CometHandler which will starts the process of suspending the underlying response.
The underlying HttpServletResponse will not get committed until
CometContext.resumeCometHandler(CometHandler) is invoked, unless the
CometContext.setExpirationDelay(long) expires.
我使用 resumeCometHandler(this) 看到了另一件事
Resume the Comet request and remove it from the active CometHandler list. Once resumed,
a CometHandler must never manipulate the HttpServletRequest or HttpServletResponse as
those object will be recycled and may be re-used to serve another request. If you cache
them for later reuse by another thread there is a possibility to introduce corrupted
responses next time a request is made.
所以我不知道是否有办法不为每个请求创建一个新的 CometHandler。我放置了一个计数器并在 onInitialize 处理程序方法中增加它,我在 onTerminate 处理程序方法中减少它,它在每个请求中增加。