웹 소켓이 닫히는 코드 1006으로 닫히는 이유 얻기


92

사용자에게 올바른 메시지를 보여줄 수 있도록 웹 소켓이 닫힌 이유를 알고 싶습니다.

나는 가지고있다

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

답변:


124

닫기 코드1006 는 브라우저 구현에 의해 연결이 비정상적으로 (로컬로) 닫 혔음을 의미하는 특수 코드입니다.

브라우저 클라이언트가 종료 코드를 1006보고하면 websocket.onerror(evt)이벤트에서 자세한 내용 을 확인해야합니다 .

그러나 Chrome은 코드 종료 1006이유를 자바 스크립트 측에 거의보고하지 않습니다 . 이는 WebSocket 악용을 방지하기위한 WebSocket 사양의 클라이언트 보안 규칙 때문일 수 있습니다. (예 : 대상 서버에서 열린 포트를 검색하거나 서비스 거부 공격을위한 많은 연결을 생성하는 데 사용).

1006Websocket으로 HTTP 업그레이드하는 동안 오류가 발생하면 Chrome은 종종 종료 코드를보고합니다 (WebSocket이 기술적으로 "연결"되기 전의 단계입니다). 잘못된 인증 또는 권한 부여, 잘못된 프로토콜 사용 (예 : 하위 프로토콜을 요청하지만 서버 자체가 동일한 하위 프로토콜을 지원하지 않음) 또는 WebSocket이 아닌 서버 위치와 통신하려는 시도와 같은 이유로 ( 에 연결 시도 등 ws://images.google.com/)

기본적으로 닫기 코드 1006가 표시되면 WebSocket 자체에 매우 낮은 수준의 오류가있는 것입니다 ( "Unable to Open File"또는 "Socket Error"와 유사). 이는 낮은 수준의 문제를 나타내므로 사용자에게 실제로 의미가 없습니다. 코드 및 구현과 함께. 낮은 수준의 문제를 수정 한 다음 연결되면 더 합리적인 오류 코드를 포함 할 수 있습니다. 프로젝트의 범위 또는 심각도 측면에서이를 수행 할 수 있습니다. 예 : 정보 및 경고 수준은 프로젝트의 특정 프로토콜의 일부이며 연결을 종료하지 않습니다. 심각하거나 치명적인 메시지보고는 프로젝트의 프로토콜을 사용하여 원하는만큼 세부 정보를 전달한 다음 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그 안에
이하 브 Khattab

@IhabKhattab은 코드에 따라 닫히고 닫힐 때도 마찬가지입니다. 갖는 sok.onclose것은 많은 경로에서 작동하지만 모든 경로에서 작동하지는 않습니다. 특히 잘못된 프로토콜, 잘못된 핸드 셰이크 오류 (예 : 코드 닫기를 유발할 수있는 일부 조건 1006). 이것이 앞으로 바뀔까요? 아마. 그러나이 답변이 쓰여졌을 때 그것은 사실이었습니다.
Joakim Erdfelt 2014 년

@JoakimErdfelt 죄송합니다, reason그가 사용했을 때 그가 반환 하지 않았다는 @slevin 질문에 답장 onerror했습니다.이 속성 code및 이벤트가 아닌 이벤트 reason에만 해당됩니다 . 그래서 그가 대신 사용 하는 것이 더 좋을 것입니다. closeerroronclose
Ihab Khattab 2014

@IhabKhattab 예, 그의 질문은 1006특별한 의미를 가진 오류 코드 와 websocket 사양의 특수 처리 및 javascript websocket api에 관한 것입니다. 일부 1006조건 에서 이유 문자열 / 메시지 는 API의 어느 곳에서도 구체적이고 의도적으로 노출되지 않습니다. (답변이 지적했듯이). 이것은 API의 버그가 아니며, 웹 소켓이 아닌 목적으로 웹 소켓을 남용하는 것에 대한 다양한 사양과 우려 사항을 해결하는 것입니다.
Joakim Erdfelt 2014 년

15

내 및 아마도 @BIOHAZARD 경우에는 nginx proxy timeout. 기본적 60으로 소켓에서 활동이없는 초입니다.

24 시간으로 변경했는데 nginx문제가 해결되었습니다.

proxy_read_timeout 86400s;
proxy_send_timeout 86400s;

감사합니다! 제 경우에는 1006 오류의 이유입니다.
Steve Hanov

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/en-US/docs/Web/API/CloseEvent#Status_codes


1

Chrome을 클라이언트로 사용하고 golang gorilla websocket을 nginx 프록시에서 서버로 사용하는 동안 오류가 발생했습니다.

그리고 x 초마다 서버에서 클라이언트로 "핑"메시지를 보내면 문제가 해결되었습니다.


0

이것은 장치에서 사용중인 웹 소켓 URL이 동일하지 않을 수 있습니다 (Android / iphonedevice에서 다른 웹 소켓 URL을 입력하고 있습니다).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.