사용자에게 올바른 메시지를 보여줄 수 있도록 웹 소켓이 닫힌 이유를 알고 싶습니다.
나는 가지고있다
sok.onerror=function (evt)
{//since there is an error, sockets will close so...
sok.onclose=function(e){
console.log("WebSocket Error: " , e);}
코드는 항상 1006이고 이유는 항상 “”입니다. 그러나 나는 다른 종결 이유를 구분하고 싶다.
예를 들어 명령 줄은 “데이터베이스가 허용하지 않기 때문에 삭제할 수 없습니다”라는 오류 이유를 제공합니다. 하지만 Chrome 콘솔에서 그 이유는 여전히 “”입니다.
다른 종결 이유를 구분하는 다른 방법이 있습니까?
답변
닫기 코드1006
는 브라우저 구현에 의해 연결이 비정상적으로 (로컬로) 닫 혔음을 의미하는 특수 코드입니다.
브라우저 클라이언트가 종료 코드를 1006
보고하면 websocket.onerror(evt)
이벤트에서 자세한 내용 을 확인해야합니다 .
그러나 Chrome은 코드 종료 1006
이유를 자바 스크립트 측에 거의보고하지 않습니다 . 이는 WebSocket 악용을 방지하기위한 WebSocket 사양의 클라이언트 보안 규칙 때문일 수 있습니다. (예 : 대상 서버에서 열린 포트를 검색하거나 서비스 거부 공격을위한 많은 연결을 생성하는 데 사용).
1006
Websocket으로 HTTP 업그레이드하는 동안 오류가 발생하면 Chrome은 종종 종료 코드를보고합니다 (WebSocket이 기술적으로 “연결”되기 전의 단계입니다). 잘못된 인증 또는 권한 부여, 잘못된 프로토콜 사용 (예 : 하위 프로토콜을 요청하지만 서버 자체가 동일한 하위 프로토콜을 지원하지 않음) 또는 WebSocket이 아닌 서버 위치와 통신하려는 시도와 같은 이유로 ( 에 연결 시도 등 ws://images.google.com/
)
기본적으로 닫기 코드 1006
가 표시되면 WebSocket 자체에 매우 낮은 수준의 오류가있는 것입니다 ( “Unable to Open File”또는 “Socket Error”와 유사). 이는 낮은 수준의 문제를 나타내므로 사용자에게 실제로 의미가 없습니다. 코드 및 구현과 함께. 낮은 수준의 문제를 수정 한 다음 연결되면 더 합리적인 오류 코드를 포함 할 수 있습니다. 프로젝트의 범위 또는 심각도 측면에서이를 수행 할 수 있습니다. 예 : 정보 및 경고 수준은 프로젝트의 특정 프로토콜의 일부이며 연결을 종료하지 않습니다. 심각하거나 치명적인 메시지보고는 프로젝트의 프로토콜을 사용하여 원하는만큼 세부 정보를 전달한 다음 WebSocket 닫기 흐름의 제한된 기능을 사용하여 연결을 닫습니다.
WebSocket 닫기 코드는 매우 엄격하게 정의되어 있으며 닫기 이유 구문 / 메시지는 길이가 123자를 초과 할 수 없습니다 (의도적 인 WebSocket 제한).
그러나 디버깅 목적으로이 정보를 원하는 경우 모든 것이 손실되는 것은 아닙니다. 폐쇄의 세부 사항 및 근본적인 이유는 종종 Chrome의 Javascript 콘솔에 상당한 양의 세부 사항과 함께보고됩니다.
답변
내 및 아마도 @BIOHAZARD 경우에는 nginx proxy timeout
. 기본적 60
으로 소켓에서 활동이없는 초입니다.
24 시간으로 변경했는데 nginx
문제가 해결되었습니다.
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
답변
Chrome이 WebSocket 표준을 준수하지 않는 경우 인 것 같습니다. 서버가 닫기를 시작 하고 닫기 프레임을 클라이언트에 보낼 때 Chrome은이를 오류로 간주하고 코드 1006 및 이유 메시지없이 JS 측에보고합니다. 내 테스트에서 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
답변
Chrome을 클라이언트로 사용하고 golang gorilla websocket을 nginx 프록시에서 서버로 사용하는 동안 오류가 발생했습니다.
그리고 x 초마다 서버에서 클라이언트로 “핑”메시지를 보내면 문제가 해결되었습니다.
답변
이것은 장치에서 사용중인 웹 소켓 URL이 동일하지 않을 수 있습니다 (Android / iphonedevice에서 다른 웹 소켓 URL을 입력하고 있습니다).