Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tomcat closes websocket conection with an error

For a customer we build a HTML5 websocket application with Tomcat 8.0.29. If we start the application from our network or from our home network all works fine. But if the customer starts the application from his network, after a certain time the websocket stops with a error. This can happen after 5 or 20 Minutes.

We have tested it with and without SSL and on two different servers. Only in the customer network the connection breaks with a error.

We also make a test with an websocket echo example which is included in Tomcat. the same as with our websocket. After a certain time the websocket stops with a error. But only if we start the application from the customer network.

When the echo example stops with an error the following message will written in 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)

If we starts the test on http://www.websocket.org/echo.html the connection will not closed with an error.

For me it looks like a problem with Tomcat. But what can I do to make it run properly?

Tomcat: 8.0.29 (also with earlier versions)
Windows 7: 64 Bit
Protocol: HTTP/1.1

like image 487
Daniel Avatar asked Dec 08 '15 12:12

Daniel


1 Answers

I apologize to the readers who came here specifically because of websockets, but we had a similar error in our application while serving files over REST API from Spring. While searching for answers, one of the places I found first was this question. Here's what I was able to find out about the error:

  1. The numbers in Unexpected error [730,054] are somehow significant and are some sort of error codes. In our case, the error looked like this: 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]. I found that this supposedly means that the connection was interrupted by the client.
  2. We were able to solve the issue by reimplementing the controller method to always return the generic ResponseEntity<Resource> object with ByteArrayResource body and content type application/octet-stream:

    responseEntity = ResponseEntity.ok()
                                   .headers(createHttpHeaders())
                                   .contentLength(file.length())
                                   .contentType(MediaType.APPLICATION_OCTET_STREAM)
                                   .body(new FileSystemResource(file));
    
  3. It appears that the errors in our case were caused by non-standard headers we were using, such as Content-Type: application/force-download. It's possible that it caused browsers to terminate the connection in a non-standard way.

like image 134
JohnEye Avatar answered Oct 11 '22 13:10

JohnEye