Java / Jetty / Wildfly:优雅地处理中止的客户端连接

时间:2015-04-21 02:43:49

标签: java javascript jetty embedded-jetty wildfly-8

我开发了一个播放音频和视频文件的Web应用程序。用户可以更改当前播放的曲目,在这种情况下,为客户端的HTML 5播放器设置新的源。应用程序的分发使用嵌入式Jetty 9,其他环境运行WildFly 8。

应用程序正常运行,但是当用户更改轨道时,WildFly会发出此堆栈跟踪:

java.io.IOException: An established connection was aborted by the software in your host machine
    at sun.nio.ch.SocketDispatcher.writev0(Native Method) [rt.jar:1.7.0_75]
    at sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:55) [rt.jar:1.7.0_75]
    at sun.nio.ch.IOUtil.write(IOUtil.java:148) [rt.jar:1.7.0_75]
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:524) [rt.jar:1.7.0_75]
    at org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:161)
    at io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:609) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    at io.undertow.conduits.AbstractFixedLengthStreamSinkConduit.write(AbstractFixedLengthStreamSinkConduit.java:148) [undertow-core-1.1.0.Final.jar:1.1.0.Final]
    ...

Jetty引发了类似的错误:

org.eclipse.jetty.io.EofException
    at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:192)
    at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:408)
    at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:302)
    at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:128)
    ...
Caused by: java.io.IOException: Broken pipe
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method)
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47)
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
    at sun.nio.ch.IOUtil.write(IOUtil.java:65)

这是有道理的 - 是的,客户端已中止与先前源文件的连接,并为下一个文件发出GET请求,但这是应用程序的预期操作。

有没有办法优雅地处理这个并避免这些错误?

1 个答案:

答案 0 :(得分:2)

如果从应用程序正在进行的调用内部抛出异常,请捕获IOException并按照您的需要进行处理 - 可能是通过返回代码正在执行的操作而不抱怨。

Tomcat有org.apache.catalina.connector.ClientAbortException,所以你可以告诉它和其他IOExceptions之间的区别,但Servlet规范没有定义可移植的异常。

如果在纯容器代码中发生异常,例如IO工作线程,那么我会提出一个错误,认为客户端断开连接会发生,所以不应该在高于调试/跟踪级别的任何事件中记录异常。