通过浏览器关闭页面导致 Websocket 错误:“已建立的连接被主机中的软件中止" [英] Websocket error by closing a page via browser: "An established connection was aborted by the software in your host machine"

查看:69
本文介绍了通过浏览器关闭页面导致 Websocket 错误:“已建立的连接被主机中的软件中止"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Spring 4 开发了一个实时通知系统.代码可在 Github 上获得:github.com/vdenotaris/Spring-Messaging强>

在我的客户端上,我使用如下脚本定义了一个 WebSocket 连接:

<html xmlns="http://www.w3.org/1999/xhtml"><头><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><脚本>var stompClient = null;功能集连接(连接){document.getElementById('connect').disabled = connected;document.getElementById('disconnect').disabled = !connected;document.getElementById('conversationDiv').style.visibility = connected ?'可见':'隐藏';document.getElementById('response').innerHTML = '';}函数连接(){var socket = new SockJS('/notifications');stompClient = Stomp.over(socket);stompClient.connect({}, function(frame) {设置连接(真);console.log('已连接:' + 框架);stompClient.subscribe('/queue/lrt-update', function(message){showMessage(message.body);});stompClient.subscribe('/user/queue/lrt-update', function(message){showMessage(message.body);});});}函数断开(){stompClient.disconnect();设置连接(假);console.log("断开连接");}功能显示消息(消息){var response = document.getElementById('response');var p = document.createElement('p');p.style.wordWrap = '断字';p.appendChild(document.createTextNode(message));response.appendChild(p);}<身体><div><button id="connect" onclick="connect();">Connect</button><button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>

<div id="conversationDiv"><p id="响应"></p>

</html>

如果我按下 Disconnect 按钮关闭连接,一切正常,但如果我通过浏览器退出整个页面,应用程序后端会抛出一些异常:

java.io.IOException: java.util.concurrent.ExecutionException: java.io.IOException: 已建立的连接被主机中的软件中止在 org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:243)在 org.apache.tomcat.websocket.WsSession.sendCloseMessage(WsSession.java:487)在 org.apache.tomcat.websocket.WsSession.onClose(WsSession.java:441)在 org.apache.tomcat.websocket.WsFrameBase.processDataControl(WsFrameBase.java:324)在 org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:270)在 org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:116)在 org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:54)在 org.apache.tomcat.websocket.server.WsHttpUpgradeHandler$WsReadListener.onDataAvailable(WsHttpUpgradeHandler.java:194)在 org.apache.coyote.http11.upgrade.AbstractServletInputStream.onDataAvailable(AbstractServletInputStream.java:189)在 org.apache.coyote.http11.upgrade.AbstractProcessor.upgradeDispatch(AbstractProcessor.java:92)在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:605)在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1720)在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1679)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)在 java.lang.Thread.run(Thread.java:744)引起:java.util.concurrent.ExecutionException: java.io.IOException: 已建立的连接被主机中的软件中止在 org.apache.tomcat.websocket.FutureToSendHandler.get(FutureToSendHandler.java:102)在 org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:238)... 省略了 16 个常用帧引起:java.io.IOException:已建立的连接被主机中的软件中止在 sun.nio.ch.SocketDispatcher.write0(本机方法)在 sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)在 sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)在 sun.nio.ch.IOUtil.write(IOUtil.java:65)在 sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:487)在 org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:123)在 org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:185)在 org.apache.coyote.http11.upgrade.NioServletOutputStream.doWriteInternal(NioServletOutputStream.java:93)在 org.apache.coyote.http11.upgrade.NioServletOutputStream.doWrite(NioServletOutputStream.java:60)在 org.apache.coyote.http11.upgrade.AbstractServletOutputStream.writeInternal(AbstractServletOutputStream.java:125)在 org.apache.coyote.http11.upgrade.AbstractServletOutputStream.write(AbstractServletOutputStream.java:92)在 org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.onWritePossible(WsRemoteEndpointImplServer.java:94)在 org.apache.tomcat.websocket.server.WsRemoteEndpointImplServer.doWrite(WsRemoteEndpointImplServer.java:81)在 org.apache.tomcat.websocket.WsRemoteEndpointImplBase.writeMessagePart(WsRemoteEndpointImplBase.java:393)在 org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessage(WsRemoteEndpointImplBase.java:287)在 org.apache.tomcat.websocket.WsRemoteEndpointImplBase.startMessageBlock(WsRemoteEndpointImplBase.java:233)... 省略了 16 个常用帧

我该如何解决?

注意:我使用 Tomcat 7 作为应用服务器.

解决方案

我遇到了同样的错误.我正在使用 websocket 服务器的 tomcat 实现.我能够通过对 onError 传入的错误调用 .getMessage() 来消除错误:

@OnErrorpublic void onError(可抛出错误){Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, error.getMessage());}

如果我像这样删除 .getMessage 调用:

Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, error);

出现错误.调用 .getMessage() 错误消失.

I've developed a real time notification system with Spring 4. The code is available on Github: github.com/vdenotaris/Spring-Messaging

On my client, I defined a WebSocket connection by using a script as follows:

<!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>

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());
}

If I remove the .getMessage call like this:

Logger.getLogger(MyServer.class.getName()).log(Level.SEVERE, null, error);

the error appears. Call .getMessage() and the error disappears.

这篇关于通过浏览器关闭页面导致 Websocket 错误:“已建立的连接被主机中的软件中止"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆