Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm implementing Server-Sent Events using Servlet 3.0's javax.servlet.AsyncContext interface.

However I can't understand how I should handle I/O errors like peer disconnect.

For a given AsyncContext ac = request.startAsync(), I can call ac.getResponse().getWriter().print(something) and then ac.getResponse.getWriter().flush() and it works fine. However when a client disconnects, I don't get an error - even if I attach a listener, its onError method is not called.

I tested it with both Jetty 8 and Tomcat 7 and it seems that the disconnect from the client is not reported back to the application.

What can be done to detect a communication error?

like image 395
Artyom Avatar asked Aug 20 '12 14:08

Artyom


2 Answers

The problem is that: ac.getResponse.getWriter().flush() does not throw IOException

So in order to get a error notification upon I/O operation you need to use ServletOutputStream instead:

try {
   ServletOutputStream out = ac.getResponse().getOutputStream();
   out.print(stuff);
   out.flush(); // throws IOException
}
catch(IOException e) {
   // handle a error
}
like image 173
Artyom Avatar answered Nov 06 '22 16:11

Artyom


There's an alternative solution, in cases where it's more convenient to use getWriter().

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

That is, the PrintWriter class does provide a method to retrieve write errors later.

like image 28
Nicholas Wilson Avatar answered Nov 06 '22 17:11

Nicholas Wilson