关于 jakarta ee:AsyncContext 和 I/O 错误处理(当对等方断开连接时)

AsyncContext and I/O error handling (when peer disconnects)

我正在使用 Servlet 3.0 的 javax.servlet.AsyncContext 接口实现服务器发送事件。

但是我不明白应该如何处理 I/O 错误,例如对等断开连接。

对于给定的AsyncContext ac = request.startAsync(),我可以调用ac.getResponse().getWriter().print(something),然后调用ac.getResponse.getWriter().flush(),它工作正常。但是,当客户端断开连接时,我不会收到错误消息 - 即使我附加了一个侦听器,它的 onError 方法也不会被调用。

我使用 Jetty 8 和 Tomcat 7 对其进行了测试,似乎没有将与客户端的断开连接报告回应用程序。

如何检测通信错误?


问题在于:ac.getResponse.getWriter().flush()不抛出IOException

因此,为了在 I/O 操作时获得错误通知,您需要使用 ServletOutputStream 代替:

1
2
3
4
5
6
7
8
try {
   ServletOutputStream out = ac.getResponse().getOutputStream();
   out.print(stuff);
   out.flush(); // throws IOException
}
catch(IOException e) {
   // handle a error
}


在使用 getWriter() 更方便的情况下,还有一个替代解决方案。

1
2
3
4
5
6
PrintWriter out = ac.getResponse().getWriter();
out.print(stuff);
out.flush(); // swallows IOException
if (out.checkError()) {
   // handle error or throw out...
}

也就是说,PrintWriter 类确实提供了稍后检索写入错误的方法。