通过密码1006获取websockets关闭的原因

时间:2013-10-10 19:05:14

标签: javascript websocket

我想了解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 个答案:

答案 0 :(得分:90)

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

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

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

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

从根本上说,如果你看到一个密切的代码1006,你的websocket本身就会出现一个非常低级别的错误(类似于“无法打开文件”或“套接字错误”),这对用户来说并不是真的意味着,因为它指向您的代码和实现的低级问题。修复您的低级问题,然后在连接时,您可以包含更合理的错误代码。您可以在项目的范围或严重性方面完成此任务。示例:信息和警告级别是项目特定协议的一部分,不会导致连接终止。使用严重或致命的消息报告也使用您的项目协议传达尽可能多的细节,然后使用websocket关闭流程的有限能力关闭连接。

请注意,WebSocket密码严格定义,密码短语/消息的长度不能超过123个字符(这是故意的websocket限制)。

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

答案 1 :(得分:3)

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

我在nginx中将其更改为24h,它解决了问题

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

答案 2 :(得分:3)

这对于其他人可能很方便。孩子们,了解正则表达式很有用。待在学校。

编辑:将其转变为便捷的花花公子功能!

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

答案 3 :(得分:1)

当Chrome不符合WebSocket标准时,情况就是这样。 当服务器启动关闭并将关闭帧发送给客户端时,Chrome认为这是错误,并使用代码1006并没有原因消息将其报告给JS端。 在我的测试中,Chrome从不响应服务器启动的关闭帧(关闭代码1000),表明代码1006可能表示Chrome正在报告自己的内部错误。

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

答案 4 :(得分:1)

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

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

答案 5 :(得分:1)

这可能是您在设备中使用的websocket URL不一样(您从android / iphonedevice中击中了不同的websocket URL)