对于客户,我们使用 Tomcat 8.0.29 构建HTML5 websocket应用程序。 如果我们从我们的网络或家庭网络启动应用程序,一切正常。但是,如果客户从他的网络启动应用程序,在一定时间后,websocket会因错误而停止。这可能在5或20分钟后发生。
我们已经使用和不使用SSL并在两台不同的服务器上对其进行了测试。只有在客户网络中,连接才会出错。
我们还使用包含在Tomcat中的websocket echo示例进行测试。与我们的websocket相同。一段时间后,websocket停止出错。但是,只有当我们从客户网络启动应用程序时。
当echo示例因错误而停止时,以下消息将写入server.log
08-Dec-2015 10:20:37.757 SEVERE [http-apr-8081-exec-2] org.apache.tomcat.websocket.pojo.PojoEndpointBase.onError No error handling configured for [websocket.echo.EchoAnnotation] and the following error occurred
java.io.IOException: Unexpected error [730,054] reading data from the APR/native socket [1,639,490,672] with wrapper [org.apache.tomcat.util.net.AprEndpoint$AprSocketWrapper@231e01e4:1639490672].<br/>
at org.apache.coyote.http11.upgrade.AprServletInputStream.doRead(AprServletInputStream.java:133)<br/>
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.read(AbstractServletInputStream.java:124)<br/>
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:51)<br/>
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:183)<br/>
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:198)<br/>
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:96)<br/>
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:669)<br/>
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2500)<br/>
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2489)<br/>
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)<br/>
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)<br/>
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)<br/>
at java.lang.Thread.run(Unknown Source)
如果我们在http://www.websocket.org/echo.html开始测试,则连接将未关闭并显示错误。
对我而言,它看起来像是Tomcat的一个问题。但我能做些什么才能让它正常运行?
Tomcat:8.0.29(也是早期版本)
Windows 7:64位
协议:HTTP / 1.1
答案 0 :(得分:1)
我特别为那些由于websocket而来到这里的读者们道歉,但是在通过Spring的REST API提供文件服务时,我们的应用程序中也出现了类似的错误。在寻找答案时,我首先发现的地方是这个问题。这是我能够找到的有关错误的信息:
Unexpected error [730,054]
中的数字在某种意义上是重要的,并且是某种错误代码。在我们的例子中,错误看起来像这样:
java.io.IOException: Unexpected error [120,001] writing data to the APR/native socket [140,041,540,128,928] with wrapper [org.apache.tomcat.util.net.AprEndpoint$AprSocketWrapper@4f1861c:140041540128928].
我发现这可能意味着该连接已被客户端中断。我们能够通过重新实现controller方法来始终返回具有ResponseEntity<Resource>
正文和内容类型ByteArrayResource
的通用application/octet-stream
对象来解决该问题:
responseEntity = ResponseEntity.ok()
.headers(createHttpHeaders())
.contentLength(file.length())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(new FileSystemResource(file));
在我们看来,该错误是由我们使用的非标准标头引起的,例如Content-Type: application/force-download
。可能导致浏览器以非标准方式终止连接。