我已经用 Spring 4 开发了一个实时通知系统。该代码可在Github上找到: github.com/vdenotaris/Spring- Messaging
在我的客户端上,我通过使用脚本定义了 WebSocket 连接,如下所示:
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Hello World!</title> <script src="/static/assets/js/stomp.min.js"></script> <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> <script> var stompClient = null; function setConnected(connected) { document.getElementById('connect').disabled = connected; document.getElementById('disconnect').disabled = !connected; document.getElementById('conversationDiv').style.visibility = connected ? 'visible' : 'hidden'; document.getElementById('response').innerHTML = ''; } function connect() { var socket = new SockJS('/notifications'); stompClient = Stomp.over(socket); stompClient.connect({}, function(frame) { setConnected(true); console.log('Connected: ' + frame); stompClient.subscribe('/queue/lrt-update', function(message){ showMessage(message.body); }); stompClient.subscribe('/user/queue/lrt-update', function(message){ showMessage(message.body); }); }); } function disconnect() { stompClient.disconnect(); setConnected(false); console.log("Disconnected"); } function showMessage(message) { var response = document.getElementById('response'); var p = document.createElement('p'); p.style.wordWrap = 'break-word'; p.appendChild(document.createTextNode(message)); response.appendChild(p); } </script> </head> <body> <div> <button id="connect" onclick="connect();">Connect</button> <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button> </div> <div id="conversationDiv"> <p id="response"></p> </div> </body> </html>
如果按“ 断开连接” 按钮关闭连接,则一切正常,但是如果我通过浏览器退出整个页面,则应用程序后端会引发一些异常:
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
我该如何解决?
注意: 我正在使用Tomcat 7作为Application Server。
我遇到了同样的错误。我正在使用websocket服务器的tomcat实现。通过onError传递的错误调用.getMessage(),我能够使错误消失:
@OnError public void onError(Throwable error) { Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, error.getMessage()); }
如果我这样删除.getMessage调用:
Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, error);
错误出现。调用.getMessage(),错误消失。