如何知道客户端已经关闭连接

6
我一直在使用Tomcat 7.0.4的新Servlet 3.0异步功能。我发现了这个聊天应用程序,它允许客户端挂起GET请求以获取消息更新。当接收消息时,这很有效。
但是,当客户端断开连接(即用户关闭浏览器)时,问题就出现了。尽管客户端已经断开连接,似乎服务器并没有引发IOException。源代码中的消息线程(请参见上面链接的源代码)仍然愉快地向所有存储的AsyncContext输出流写入数据。
这是一个Tomcat的bug吗?还是我漏掉了什么?如果这不是一个bug,那么我该如何检测客户端是否已关闭连接?
1个回答

1

代码中的第44-47行正在处理它,

} catch(IOException ex) {
    System.out.println(ex);
    queue.remove(ac);
}

在这里,使用超时机制,在75-83行。

req.addAsyncListener(new AsyncListener() {
    public void onComplete(AsyncEvent event) throws IOException {
        queue.remove(ac);
    }

    public void onTimeout(AsyncEvent event) throws IOException {
        queue.remove(ac);
    }
});

编辑:在获得更多见解后。

  1. Tomcat 7.0.4仍处于测试版阶段,因此您可以预期会出现这种行为
  2. 我努力尝试了一下,但在文档中找不到setAsyncTimeout()方法,无论是这里还是这里。因此,我认为由于某些未知的有效原因,它们在最终版本中完全删除了它
  3. 示例说明:“为什么我应该使用框架而不是等待Servlet 3.0 Async API”。这意味着它是在最终版本之前编写的

因此,结合所有这些事实,我可以说,您正在尝试使用某种意义上已经损坏的东西。这也可能是产生不同和奇怪结果的原因。


我尝试在Glassfish v3上运行这段代码,似乎可以在Firefox中获取onError事件,但在IE中无法工作。这真的很奇怪。 - SS3
我关闭了整个浏览器而不仅仅是选项卡。这仍然无法解释为什么一些浏览器可以使用Glassfish而另一些则不能使用Tomcat。必须存在一些实现问题。 - SS3
超时是AsyncContext的属性,而不是ServletResponse的属性。超时是有问题的,因为如果异步请求在给定的时间限制内没有完成,容器将终止它。我不确定向AsyncContext的响应中写入内容是否会重置此计时器。 - SS3
好的,我会发布一个带有精确代码的新问题。但最终我认为这不会有任何区别。谢谢你的回复。 - SS3
@SS3:也许在查看您的代码后,我们能够解决这个问题。我们已经花了很多时间在这上面,至少我们必须尝试得出一些结论。你怎么说? - Adeel Ansari
显示剩余10条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接