You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Safari中WebSocket断开时close/error事件不触发问题求助

iOS Safari WebSocket 连接断开未触发 close/error 事件问题

iOS Safari 在 WebSocket 连接断开时不会触发对应的 close 和 error 事件,导致Web应用无法感知连接已丢失。而Android设备上,连接一旦断开,close 和 error 事件会立即触发。

复现示例

Node.js WebSocket服务器

const WebSocket = require('ws');
const wss = new WebSocket.Server({port: 8080});
wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        ws.send(`You sent: ${message}`);
    });
    ws.on('close', function close() {
        console.log('Client has disconnected');
    });
});

客户端HTML代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>WebSocket Example</title>
</head>
<body>
<h1>WebSocket Example</h1>
<div id="output"></div>
<form>
    <label>
        Message:
        <input type="text" id="message">
    </label>
    <button type="submit" id="send">Send</button>
</form>
<script>
    const output = document.getElementById('output');
    const messageInput = document.getElementById('message');
    const sendButton = document.getElementById('send');
    const ws = new WebSocket('ws://localhost:8080');
       
    ws.addEventListener('open', function (event) {
        console.log((new Date()).toISOString(), '********************** OPEN **********************');
    });

    ws.addEventListener('close', function (event) {
        console.log((new Date()).toISOString(), '********************** CLOSE **********************');
    });

    ws.addEventListener('error', function (event) {
        console.log((new Date()).toISOString(), '********************** ERROR **********************');
    });

    ws.addEventListener('message', function (event) {
        console.log((new Date()).toISOString(), '********************** MESSAGE **********************');

        // Append the message to the output div
        const message = document.createElement('p');
        message.textContent = event.data;
        output.appendChild(message);
    });

    sendButton.addEventListener('click', function (event) {
        event.preventDefault();

        const message = messageInput.value;

        // Send the message to the server
        ws.send(message);
    });
</script>
</body>
</html>

测试场景

运行上述代码后,当WebSocket连接断开(例如开启飞行模式、关闭WiFi路由器、关闭设备WiFi),iOS Safari不会触发close或error事件。此问题仅出现在iOS Safari中,Android及其他设备表现正常。

2023年5月18日更新

已发现相关Webkit官方Bug报告。临时解决方案可通过监听window.onoffline事件提示用户连接异常,期待官方尽快修复该问题。


内容的提问来源于stack exchange,提问作者Thibs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:29