获取关闭代码 1006 关闭 websockets 的原因

IT技术 javascript websocket
2021-02-04 23:10:08

我想知道 websockets 关闭的原因,所以我可以向用户显示正确的消息。

我有

sok.onerror=function (evt) 
     {//since there is an error, sockets will close so...
       sok.onclose=function(e){
           console.log("WebSocket Error: " , e);}

代码始终为 1006,原因始终为“ ”。但我想区分不同的关闭原因。

例如,命令行给出了一个错误原因:“你不能删除那个,因为数据库不会让你”。但是在Chrome的控制台上,原因还是“ ”。

还有其他方法可以区分不同的关闭原因吗?

6个回答

关闭代码1006是一种特殊代码,表示浏览器实现异常(本地)关闭了连接。

如果您的浏览器客户端报告 close code 1006,那么您应该查看websocket.onerror(evt)事件以获取详细信息。

但是,Chrome 很少会1006向 Javascript 端报告任何关闭代码的原因。这可能是由于 WebSocket 规范中的客户端安全规则可以防止滥用 WebSocket。(例如使用它来扫描目标服务器上的开放端口,或为拒绝服务攻击生成大量连接)。

请注意,1006如果在 HTTP 升级到 Websocket 期间出现错误(这是技术上“连接”WebSocket 之前的步骤),Chrome 通常会报告关闭代码由于错误的身份验证或授权,或错误的协议使用(例如请求子协议,但服务器本身不支持相同的子协议),甚至尝试与不是 WebSocket 的服务器位置通信(例如尝试连接到ws://images.google.com/)

从根本上说,如果你看到一个关闭的代码1006,你有一个非常低级的 WebSocket 错误(类似于“无法打开文件”或“套接字错误”),并不是真正针对用户的,因为它指向一个低级问题与您的代码和实现。修复您的低级问题,然后当您连接时,您可以包含更合理的错误代码。您可以根据项目的范围或严重性来实现这一点。示例:信息和警告级别是项目特定协议的一部分,不会导致连接终止。对于严重或致命的消息报告,还使用您的项目协议来传达您想要的尽可能多的细节,然后使用 WebSocket 关闭流的有限功能关闭连接。

请注意,WebSocket 关闭代码的定义非常严格,关闭原因短语/消息的长度不能超过 123 个字符(这是一个有意的 WebSocket 限制)。

但并不是所有的都丢失了,如果您只是出于调试原因想要这些信息,那么关闭的详细信息及其根本原因通常会在 Chrome 的 Javascript 控制台中以相当多的详细信息报告。

你应该使用sok.onclosewhich triggers close event,它有reasoncode在里面
2021-03-19 23:10:08
在我的情况下,同样的 1006 错误即将到来,但这是在 Chrome、Firefox 等的情况下发生的,而不是在 iOS 设备的 Opera 或 Safari 的情况下。如果有人有想法,请帮助我,stackoverflow.com/questions/30799814/...
2021-03-19 23:10:08
Joakim,谢谢,非常详细的分析。如果我使用sok.onerror=function (evt) {console.log(evt);}的细节没有那么多。甚至不是reason什么。那么,根本没有选择?我只是向用户展示,something is wrong, or not connencted?不是那么人性化,如果用户能看到“您无法删除,数据库限制原因”就太好了。有什么选择吗?谢谢
2021-04-02 23:10:08
@JoakimErdfelt 抱歉,我正在回答@slevin 的问题,关于他reason在使用时没有返回onerror我指出此属性code&reason特定于close事件而不是error事件。所以它会是更好的为他onclose,而不是,我失去的东西吗?
2021-04-03 23:10:08
@IhabKhattab 这将是特定于关闭代码的,以及关闭发生时。havesok.onclose将适用于许多路径,但不是所有路径。特别是糟糕的协议,糟糕的握手错误(比如一些可能导致关闭代码的情况1006)。这在未来会改变吗?大概。但是当这个答案写出来时,它是真的。
2021-04-04 23:10:08

在我和可能的@BIOHAZARD 案例中,它是nginx proxy timeout. 默认情况60下,套接字中没有活动

我将其更改为 24hnginx并解决了问题

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
谢谢你!在我的情况下,这就是 1006 错误的原因。
2021-04-09 23:10:08

当 Chrome 不符合 WebSocket 标准时,情况似乎就是这种情况。服务器发起关闭并向客户端发送关闭帧时,Chrome 认为这是一个错误,并向 JS 端报告代码 1006 和无原因消息。在我的测试中,Chrome 从不响应服务器启动的关闭帧(关闭代码 1000),这表明代码 1006 可能意味着 Chrome 正在报告自己的内部错误。

PS Firefox v57.00 正确处理了这种情况,并成功地将服务器的原因消息传递给了 JS 端。

认为这对其他人可能很方便。知道正则表达式很有用,孩子们。呆在学校。

编辑:把它变成了一个方便的花花公子功能!

let specificStatusCodeMappings = {
    '1000': 'Normal Closure',
    '1001': 'Going Away',
    '1002': 'Protocol Error',
    '1003': 'Unsupported Data',
    '1004': '(For future)',
    '1005': 'No Status Received',
    '1006': 'Abnormal Closure',
    '1007': 'Invalid frame payload data',
    '1008': 'Policy Violation',
    '1009': 'Message too big',
    '1010': 'Missing Extension',
    '1011': 'Internal Error',
    '1012': 'Service Restart',
    '1013': 'Try Again Later',
    '1014': 'Bad Gateway',
    '1015': 'TLS Handshake'
};

function getStatusCodeString(code) {
    if (code >= 0 && code <= 999) {
        return '(Unused)';
    } else if (code >= 1016) {
        if (code <= 1999) {
            return '(For WebSocket standard)';
        } else if (code <= 2999) {
            return '(For WebSocket extensions)';
        } else if (code <= 3999) {
            return '(For libraries and frameworks)';
        } else if (code <= 4999) {
            return '(For applications)';
        }
    }
    if (typeof(specificStatusCodeMappings[code]) !== 'undefined') {
        return specificStatusCodeMappings[code];
    }
    return '(Unknown)';
}

用法:

getStatusCodeString(1006); //'Abnormal Closure'

{
    '0-999': '(Unused)',
    '1016-1999': '(For WebSocket standard)',
    '2000-2999': '(For WebSocket extensions)',
    '3000-3999': '(For libraries and frameworks)',
    '4000-4999': '(For applications)'
}

{
    '1000': 'Normal Closure',
    '1001': 'Going Away',
    '1002': 'Protocol Error',
    '1003': 'Unsupported Data',
    '1004': '(For future)',
    '1005': 'No Status Received',
    '1006': 'Abnormal Closure',
    '1007': 'Invalid frame payload data',
    '1008': 'Policy Violation',
    '1009': 'Message too big',
    '1010': 'Missing Extension',
    '1011': 'Internal Error',
    '1012': 'Service Restart',
    '1013': 'Try Again Later',
    '1014': 'Bad Gateway',
    '1015': 'TLS Handshake'
}

来源(为简洁起见略作修改):https : //developer.mozilla.org/en-US/docs/Web/API/CloseEvent#Status_codes

@Andrew 您可以从单词 wsCloseCodes['PolicyViolation'] 或单词 wsCloseCodes[1008] 中获取数字
2021-03-16 23:10:08
@Piranna 继续。;)
2021-03-20 23:10:08
websocket-close-codes npm 包有代码。
2021-03-29 23:10:08
npm 包怎么样?:-)
2021-04-04 23:10:08
@whistling_marmot 只在一个方向(为了任何合理的效率)。
2021-04-04 23:10:08

在 nginx 代理下使用 Chrome 作为客户端并使用 golang gorilla websocket 作为服务器时出现错误

并且每隔 x 秒从服务器向客户端发送一些“ping”消息解决了问题

更新:哦,男孩,我在这个答案之后实现了几十个基于 websocket 的应用程序,每 5 秒从客户端 PINGING是保持与服务器连接的正确方法(我不知道当我建议从服务器 ping 时我在想什么)