正确关闭WebSocket(HTML5、Javascript)

dohp0rv5  于 2022-11-11  发布在  HTML5
关注(0)|答案(6)|浏览(1943)

我正在玩HTML5 WebSockets。我想知道,我如何优雅地关闭连接?比如,如果用户刷新页面,或者只是关闭浏览器,会发生什么?
当用户只是刷新页面而不调用websocket.close()时,会出现一种奇怪的行为--当用户在刷新后返回时,会遇到websocket.onclose事件。

izj3ouym

izj3ouym1#

根据protocol spec v76(当前支持的浏览器实现的版本):
为了干净地关闭连接,从一个对等方发送仅由0xFF字节后跟0x00字节组成的帧,以请求另一个对等方关闭连接。
如果你正在写一个服务器,你应该确保当服务器关闭一个客户端连接时发送一个关闭帧。正常的TCP套接字关闭方法有时会很慢,并导致应用程序认为连接仍然打开,即使它没有打开。
当你关闭或重新加载页面时,浏览器应该会自动执行这个操作。但是,你可以通过捕获beforeunload事件来确保发送一个关闭帧:

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

我不知道如何在页面刷新后获得onclose事件。WebSocket对象如果您在页面加载时立即尝试在页面上建立WebSocket连接,那么您可能会遇到一个问题,即服务器在旧连接断开后不久就拒绝新连接(或者浏览器还没有准备好在您尝试连接的点进行连接),并且您将获得新WebSocket对象的onclose事件。

btqmn9zl

btqmn9zl2#

现在使用的WebSockets主要有两个协议版本,旧版本使用[0x00][message][0xFF]协议,而新版本使用Hybi格式的数据包
Opera和iPod/iPad/iPhone使用的是旧的协议版本,所以在WebSockets服务器中实现向后兼容性实际上是很重要的。对于这些使用旧协议的浏览器,我发现刷新页面、离开页面或关闭浏览器都会导致浏览器自动关闭连接。太棒了!!
但是对于使用新协议版本的浏览器(例如Firefox,Chrome和最终的IE10),只有关闭浏览器才会导致浏览器自动关闭连接。也就是说,如果您刷新页面,或导航离开页面,浏览器不会自动关闭连接。然而,浏览器所做的是,向服务器发送一个hybi包,第一个字节(proto ident)为0x88(通常称为close data frame),一旦服务器收到这个包,它可以强制关闭连接。

deyfvvtc

deyfvvtc3#

非常简单,你关闭它:)

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

你也检查了following site了吗?

68bkxrlz

68bkxrlz4#

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

cdmah0mi

cdmah0mi5#

请用这个

var uri = "ws://localhost:5000/ws";
var socket = new WebSocket(uri);
socket.onclose = function (e){
    console.log(connection closed);
};
window.addEventListener("unload", function () {
    if(socket.readyState == WebSocket.OPEN)
        socket.close();
});

关闭浏览器不会触发WebSocket关闭事件。您必须手动呼叫socket.close()

oalqel3c

oalqel3c6#

通过使用Web Socket的close方法,可以根据需要编写任意函数。

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

相关问题