0


我开始尝试 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 处理程序方法中减少它,它在每个请求中增加。

4

1 回答 1

0

最后似乎没有问题。
虽然每个请求都会创建一个处理程序,但它会从列表中删除,并在调用垃圾收集器时被清除。
为了尝试它,我强制执行 gc,并且每个不在挂起列表中的 CometHandler 都已完成。
我尝试强制执行大量新请求,并在实例化大量彗星处理程序时调用垃圾收集器,因此我仍然不太喜欢这种方法。
欢迎每一个新想法。
问候

于 2012-10-02T12:01:30.257 回答