通过浏览器关闭页面导致 Websocket 错误:“已建立的连接被主机中的软件中止"
[英] Websocket error by closing a page via browser: "An established connection was aborted by the software in your host machine"
If I close the connection by pressing the Disconnect button, all works fine, but if I quit the whole page via browser, the application back-end throws some exceptions:
java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: An established connection was aborted by the software in your host machine
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:243)
at org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:487)
at org.apache.tomcat.websocket.WsSession.onClose(WsSession.java:441)
at org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:324)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:270)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:116)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:54)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:194)
at org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:189)
at org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:92)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:605)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1720)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.util.concurrent.ExecutionException: java.io.IOException: An established connection was aborted by the software in your host machine
at org.apache.tomcat.websocket.FutureToSendHandler.get(FutureToSendHandler.java:102)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:238)
... 16 common frames omitted
Caused by: java.io.IOException: An established connection was aborted by the software in your host machine
at sun.nio.ch.SocketDispatcher.write0(Native Method)
at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
at sun.nio.ch.IOUtil.write(IOUtil.java:65)
at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:487)
at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:123)
at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:185)
at org.apache.coyote.http11.upgrade.NioServletOutputStream.doWriteInternal(NioServletOutputStream.java:93)
at org.apache.coyote.http11.upgrade.NioServletOutputStream.doWrite(NioServletOutputStream.java:60)
at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.writeInternal(AbstractServletOutputStream.java:125)
at org.apache.coyote.http11.upgrade.AbstractServletOutputStream.write(AbstractServletOutputStream.java:92)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:94)
at org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:393)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:287)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:233)
... 16 common frames omitted
How can I fix it?
Note: I'm using Tomcat 7 as Application Server.
解决方案
I was getting this same error. I'm using the tomcat implementation of websocket server. I was able to make the error go away by calling .getMessage() on the error passed in by onError:
@OnError
public void onError(Throwable error)
{
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, error.getMessage());
}