了解为什么 websockets 以关闭代码1006关闭

我想得到的原因 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 的控制台上,原因仍然是“”。

还有别的办法区分不同的结案理由吗?

313416 次浏览

关闭代码 1006 是一个特殊的代码,这意味着浏览器实现在本地非正常地关闭了连接。

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

然而,Chrome 很少向 Javascript 方面报告任何关闭代码 1006的原因。这可能是由于 WebSocket 规范中的客户机安全规则防止了 WebSocket 的滥用。(比如用它来扫描目标服务器上打开的端口,或者为一个分布式拒绝服务攻击生成大量连接)。

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

从根本上说,如果你看到一个关闭的代码 1006,你有一个非常低级的错误与 WebSocket 本身(类似于“无法打开文件”或“ Socket 错误”) ,并不真正意味着为用户,因为它指出了一个低级别的问题与您的代码和实现。修复您的底层问题,然后当您连接时,您可以包括更合理的错误代码。您可以根据项目的范围或严重程度来完成此任务。示例: info 和警告级别是项目特定协议的一部分,不会导致连接终止。严重或致命的消息报告也使用您的项目的协议来传递尽可能多的细节,然后使用 WebSocket 关闭流的有限功能关闭连接。

Be aware that WebSocket close codes are very strictly defined, and the close reason phrase/message cannot exceed 123 characters in length (this is an intentional WebSocket limitation).

但是并不是所有的信息都丢失了,如果你只是因为调试的原因想要这些信息,关闭的细节,以及它的潜在原因通常会在 Chrome 的 Javascript 控制台中报告相当多的细节。

看起来 Chrome 不符合 WebSocket 标准就是这种情况。 When the 服务器启动关闭 and sends close frame to a client, Chrome considers this to be an error and reports it to JS side with code 1006 and no reason message. 在我的测试中,Chrome 从未响应服务器发起的关闭帧(关闭代码1000) ,这表明代码1006可能意味着 Chrome 报告了自己的内部错误。

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

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

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

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

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

我把 nginx改成24小时,问题解决了

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

这可能是你在设备中使用的网络套接字 URL 不一样(你点击的网络套接字 URL 与 android/iphone 设备不同)

我想这对其他人也许有用,知道正则表达式是有用的,孩子们,留在学校。

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

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

把这个作为一个可能的原因,而不是回答这个问题。

这个问题我们只影响了基于铬的浏览器。

我们有一个负载平衡器和浏览器发送更多的字节比协商在握手导致负载平衡器终止连接。

TCP 窗口缩放为我们解决了这个问题。

We had the same problem and actually AWS was our problem.

Setup Websocket 连接-> AWS EC2 Loadbalancer-> Nginx Proxy-> Node.js Backend

我们增加了基于上面 Nginx 会议的 这个答案的超时,但是没有看到任何改进。我们现在发现 AWS 负载均衡器还有一个默认为60秒的超时。您可以在 EC2-> Loadbalancer< img src = “ https://i.stack.imgur.com/GK2mW.png”alt = “ enter image description here”/> < img src = “ https://i.stack.imgur.com/GK2mW.png”alt = “在这里输入图片描述”/> 下编辑它。

请注意,我们没有实现乒乓球方案。我们认为实现一个应用程序也会解决这个问题,直到我们使用这个解决方案并增加空闲超时时间为止。