获取为什么websockets用关闭代码1006关闭的原因


92

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

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


我认为这是由于服务器如何处理连接/断开的事件。我不能肯定地说,但是连接关闭也需要使用代码在服务器上正确处理。尝试覆盖服务器上的内置On Connected / Disconnected方法,然后查看。我的假设仅仅是您要关闭它,但是服务器没有正确关闭,因此不能中继正确的关闭响应。
Michael Puckett II '18

Answers:


123

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

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

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

请注意,1006如果HTTP升级到Websocket时发生错误,Chrome通常会报告关闭代码(这是从技术上“连接” WebSocket之前的步骤)。由于诸如身份验证或授权不正确或协议使用不当(例如请求子协议,但服务器本身不支持该子协议)之类的原因,甚至是试图与非WebSocket的服务器位置进行通信的原因(例如尝试连接到ws://images.google.com/

从根本上讲,如果您看到一个关闭的代码1006,则WebSocket本身有一个非常低级的错误(类似于“无法打开文件”或“套接字错误”),并不是真正的用户,因为它指出了一个低级问题与您的代码和实现。解决您的低级问题,然后在连接时可以包含更合理的错误代码。您可以根据项目的范围或严重性来完成此操作。示例:信息和警告级别是项目特定协议的一部分,不会导致连接终止。使用严重或致命消息进行报告时,还可以使用项目的协议来传达所需的详细信息,然后使用WebSocket关闭流的有限功能来关闭连接。

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

但是,如果您只是出于调试原因而需要此信息,那么关闭的详细信息以及其潜在原因,并不是所有信息都会丢失,但通常会在Chrome的Javascript控制台中报告大量详细信息。


4
Joakim,谢谢,非常详细的分析服务。如果我使用sok.onerror=function (evt) {console.log(evt);}的细节不是很多。甚至没有一个reason。所以,根本没有选择吗?我只是向用户显示,something is wrong, or not connencted?不是那么用户友好,如果用户看到“您不能删除,数据库限制的原因”,那就太好了。有什么选择吗?谢谢
slevin

您应该使用sok.onclose,而不是它的触发器close event,它reasoncode
伊哈卜·哈塔卜

@IhabKhattab特定于关闭代码,以及关闭发生的时间。具有sok.onclose许多路径,但不是所有路径。特别糟糕的协议,错误的握手错误(例如可能导致关闭代码的某些情况1006)。将来会改变吗?大概。但是,当写出这个答案时,它是真的。
2014年

@JoakimErdfelt抱歉,我在回复@slevin的问题是关于他reason使用他时没有归来,onerror我指的是此属性codereason特定于close事件而非error事件。所以最好让他使用onclose,我是否缺少某些东西?
Ihab Khattab 2014年

@IhabKhattab是的,因为他的问题是关于1006具有特殊含义的错误代码以及websocket规范和javascript websocket api中的特殊处理的特定问题。在某些1006情况下,原因字符串/消息在API中的任何地方都没有明确地有意公开。(如答案所指出)。这不是API中的错误,它仅解决了各种规范及其对出于非websocket目的滥用websocket的担忧。
2014年

15

就我而言,可能是@BIOHAZARD nginx proxy timeout。默认情况60下,套接字无活动的时间是秒

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

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

谢谢你!这是我的情况下1006错误的原因。
史蒂夫·哈诺夫

11

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

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


2

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

编辑:变成了方便的花花公子功能!

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/zh-CN/docs/Web/API/CloseEvent#Status_codes


1

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

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.