正确关闭 WebSocket(HTML5、Javascript)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4812686/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:12:54  来源:igfitidea点击:

Closing WebSocket correctly (HTML5, Javascript)

javascriptsocketshtmlwebsocket

提问by Andy Hin

I am playing around with HTML5 WebSockets. I was wondering, how do I close the connection gracefully? Like, what happens if user refreshes the page, or just closes the browser?

我在玩 HTML5 WebSockets。我想知道,如何优雅地关闭连接?比如,如果用户刷新页面或关闭浏览器会发生什么?

There is a weird behavior when a user just refresh the page without calling websocket.close()- when they return after the refresh it will hit the websocket.oncloseevent.

当用户在没有调用的情况下刷新页面时会出现一种奇怪的行为websocket.close()- 当他们在刷新后返回时,它会触发websocket.onclose事件。

回答by kanaka

According to the protocol specv76 (which is the version that browser with current support implement):

根据协议规范v76(当前支持的浏览器实现的版本):

To close the connection cleanly, a frame consisting of just a 0xFF byte followed by a 0x00 byte is sent from one peer to ask that the other peer close the connection.

为了干净地关闭连接,从一个对等方发送一个仅由 0xFF 字节后跟一个 0x00 字节组成的帧,以要求另一个对等方关闭连接。

If you are writing a server, you should make sure to send a close frame when the server closes a client connection. The normal TCP socket close method can sometimes be slow and cause applications to think the connection is still open even when it's not.

如果您正在编写服务器,则应确保在服务器关闭客户端连接时发送关闭帧。正常的 TCP 套接字关闭方法有时会很慢,并导致应用程序认为连接仍然打开,即使它没有打开。

The browser should really do this for you when you close or reload the page. However, you can make sure a close frame is sent by doing capturing the beforeunload event:

当您关闭或重新加载页面时,浏览器应该真正为您执行此操作。但是,您可以通过捕获 beforeunload 事件来确保发送关闭帧:

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

I'm not sure how you can be getting an onclose event after the page is refreshed. The websocket object (with the onclose handler) will no longer exist once the page reloads. If you are immediately trying to establish a WebSocket connection on your page as the page loads, then you may be running into an issue where the server is refusing a new connection so soon after the old one has disconnected (or the browser isn't ready to make connections at the point you are trying to connect) and you are getting an onclose event for the new websocket object.

我不确定页面刷新后如何获得 onclose 事件。一旦页面重新加载,websocket 对象(带有 onclose 处理程序)将不再存在。如果您在页面加载时立即尝试在您的页面上建立 WebSocket 连接,那么您可能会遇到一个问题,即服务器在旧连接断开后很快拒绝新连接(或浏览器未准备好)在您尝试连接时建立连接),并且您将收到新 websocket 对象的 onclose 事件。

回答by karlcow

Very simple, you close it :)

很简单,你关闭它:)

var myWebSocket = new WebSocket("ws://example.org"); 
myWebSocket.send("Hello Web Sockets!"); 
myWebSocket.close();

Did you check also the following siteAnd check the introduction article of Opera

您是否还检查了以下站点并检查了Opera介绍文章

回答by theoobe

The thing of it is there are 2 main protocol versions of WebSockets in use today. The old version which uses the [0x00][message][0xFF]protocol, and then there's the new version using Hybi formatted packets.

问题是目前使用的 WebSockets 有 2 个主要协议版本。使用[0x00][message][0xFF]协议的旧版本,然后是使用混合格式数据包的新版本。

The old protocol version is used by Opera and iPod/iPad/iPhones so it's actually important that backward compatibility is implemented in WebSockets servers. With these browsers using the old protocol, I discovered that refreshing the page, or navigating away from the page, or closing the browser, all result in the browser automatically closing the connection. Great!!

Opera 和 iPod/iPad/iPhone 使用旧协议版本,因此在 WebSockets 服务器中实现向后兼容性实际上很重要。在这些使用旧协议的浏览器中,我发现刷新页面、离开页面或关闭浏览器都会导致浏览器自动关闭连接。伟大的!!

However with browsers using the new protocol version (eg. Firefox, Chrome and eventually IE10), only closing the browser will result in the browser automatically closing the connection. That is to say, if you refresh the page, or navigate away from the page, the browser does NOT automatically close the connection. However, what the browser does do, is send a hybi packet to the server with the first byte (the proto ident) being 0x88(better known as the close data frame). Once the server receives this packet it can forcefully close the connection itself, if you so choose.

但是,对于使用新协议版本的浏览器(例如 Firefox、Chrome 和最终的 IE10),只有关闭浏览器才会导致浏览器自动关闭连接。也就是说,如果您刷新页面或离开页面,浏览器不会自动关闭连接。然而,浏览器所做的是向服务器发送一个 hybi 数据包,其中第一个字节(原型标识)是0x88(更好地称为关闭数据帧)。一旦服务器收到这个数据包,它可以强制关闭连接本身,如果你愿意的话。

回答by artkoenig

As mentioned by theoobe, some browsers do not close the websockets automatically. Don't try to handle any "close browser window" events client-side. There is currently no reliable way to do it, if you consider support of major desktop ANDmobile browsers (e.g. onbeforeunloadwill not work in Mobile Safari). I had good experience with handling this problem server-side. E.g. if you use Java EE, take a look at javax.websocket.Endpoint, depending on the browser either the OnClosemethod or the OnErrormethod will be called if you close/reload the browser window.

正如theoobe所提到的,某些浏览器不会自动关闭 websocket。不要尝试在客户端处理任何“关闭浏览器窗口”事件。如果您考虑支持主要的桌面移动浏览器(例如onbeforeunload在 Mobile Safari 中不起作用),目前没有可靠的方法可以做到这一点。我在服务器端处理这个问题方面有很好的经验。例如,如果您使用 Java EE,请查看javax.websocket.Endpoint,这取决于浏览器,如果您关闭/重新加载浏览器窗口,将调用该OnClose方法或OnError方法。

回答by Akanksha Raizada

By using close method of web socket, where you can write any function according to requirement.

通过使用web socket的close方法,你可以根据需要编写任何函数。

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };