WebSocket을 올바르게 닫기 (HTML5, Javascript)


127

HTML5 WebSockets로 놀고 있습니다. 궁금한 점이있었습니다. 어떻게 연결을 정상적으로 닫을 수 있습니까? 예를 들어, 사용자가 페이지를 새로 고치거나 브라우저를 닫으면 어떻게됩니까?

사용자가 호출하지 않고 페이지를 새로 고치면 이상한 동작이 있습니다 websocket.close(). 새로 고친 후 돌아 오면 websocket.onclose이벤트 가 발생합니다 .

답변:


110

에 따라 프로토콜 사양 (현재 지원하는 브라우저가 구현하는 버전입니다) v76 :

연결을 깨끗하게 닫으려면 한 피어에서 0xFF 바이트와 0x00 바이트로 구성된 프레임을 보내 다른 피어가 연결을 닫으라고 요청합니다.

서버를 작성하는 경우 서버가 클라이언트 연결을 닫을 때 닫기 프레임을 보내야합니다. 일반적인 TCP 소켓 닫기 방법은 때때로 느려질 수 있으며 연결이 아직 열려 있지 않아도 응용 프로그램에서 연결이 여전히 열려 있다고 생각하게합니다.

페이지를 닫거나 다시로드 할 때 브라우저에서 실제로이 작업을 수행해야합니다. 그러나 beforeunload 이벤트를 캡처하여 가까운 프레임이 전송되도록 할 수 있습니다.

window.onbeforeunload = function() {
    websocket.onclose = function () {}; // disable onclose handler first
    websocket.close();
};

페이지를 새로 고친 후 onclose 이벤트를 어떻게받을 수 있는지 잘 모르겠습니다. 페이지가 다시로드되면 웹 소켓 객체 (onclose 핸들러 사용)가 더 이상 존재하지 않습니다. 페이지가로드 될 때 페이지에서 즉시 WebSocket 연결을 설정하려고하면 이전 연결이 끊어진 직후 (또는 브라우저가 준비되지 않은) 서버가 새 연결을 거부하는 문제가 발생할 수 있습니다. 연결하려는 시점에서 연결하기 위해) 새 websocket 객체에 대한 onclose 이벤트가 발생합니다.


2
Firefox에서 연결이 다음 페이지로드에 걸리는 것처럼 보일 수 있습니다. 참조를 찾을 수 없지만 이것에 대한 버그가 있다고 생각합니다. 다른 가능성은 onclose사용자가 탐색 / 페이지를 다시로드 할 때 이벤트가 예기치 않게 트리거되거나 의도적으로 트리거 될 수 있습니다. 내가 한 질문 게시 권리와 우리가 어떻게 자동 재 연결을 구현을 가지고 브라우저 예상되는 동작이 있어야 할 무엇을 묻는.
leggetter 2016 년

4
이벤트 와 관련된 이러한 문제 를 고려onbeforeunload
artkoenig


35

오늘날 사용중인 WebSockets에는 두 가지 주요 프로토콜 버전이 있습니다. [0x00][message][0xFF]프로토콜 을 사용하는 이전 버전 과 Hybi 형식의 패킷을 사용하는 새 버전이 있습니다.

이전 프로토콜 버전은 Opera 및 iPod / iPad / iPhone에서 사용되므로 WebSockets 서버에서 이전 버전과의 호환성을 구현하는 것이 중요합니다. 이전 프로토콜을 사용하는 이러한 브라우저에서 페이지를 새로 고치거나 페이지를 탐색하거나 브라우저를 닫으면 브라우저가 자동으로 연결을 닫는다는 것을 발견했습니다. 큰!!

그러나 새 프로토콜 버전 (예 : Firefox, Chrome 및 결국 IE10)을 사용하는 브라우저의 경우 브라우저 만 닫으면 브라우저가 자동으로 연결을 닫습니다. 즉, 페이지를 새로 고치거나 페이지를 벗어나면 브라우저가 자동으로 연결을 닫지 않습니다. 그러나 브라우저가하는 일은 첫 번째 바이트 (proto ident) 0x88(더 나은 데이터 프레임이라고 함 )가있는 서버로 hybi 패킷을 보내는 것 입니다. 서버가이 패킷을 수신하면 원하는 경우 연결 자체를 강제로 닫을 수 있습니다.


4
서버 쪽에서이 hybi 패킷을 관리하는 방법에 대한 실제적인 예?
albanx

9
연결을 닫지 않는 것은 미친 것 같습니다. 페이지 재로드시 WebSocket 변수가 지워 지므로 액세스 할 수없는 경우 연결이 열린 상태로 유지되는 이유는 무엇입니까? 연결을 재사용하는 것도 의미가 없습니다.
Triynko

내 대답은 아래를 확인 @albanx
artkoenig

웹 소켓 클라이언트 (예 : 브라우저)에서 가까운 프레임을 보내는 방법에 대한 모든 코드 샘플. 나는 WS NPM 모듈을 사용하고 있습니다
Shaik 에드 알리

3

theoobe 에서 언급했듯이 일부 브라우저는 웹 소켓을 자동으로 닫지 않습니다. 클라이언트 측에서 "브라우저 창 닫기"이벤트를 처리하지 마십시오. 주요 데스크탑 모바일 브라우저 (예 : onbeforeunloadMobile Safari에서 작동하지 않음)를 지원하는 경우 현재로서는 신뢰할 수있는 방법 이 없습니다. 이 문제를 서버 측에서 처리 한 경험이 좋았습니다. 예를 들어 Java EE를 사용 하는 경우 브라우저에 따라 javax.websocket.Endpoint를 살펴보십시오 . 브라우저 창을 닫거나 다시로드하면 OnClose메소드 또는 OnError메소드가 호출됩니다.


1
필자의 경우 데이터 전송 중에 연결이 닫히고 Opera 및 iOS 제품군 브라우저의 경우 잘 작동합니다. 저를 도와주세요 .. 지난 2 주간이 문제와 싸우고 있습니다. stackoverflow.com/q/30799814/2225439
Mrug

2

요구 사항에 따라 모든 기능을 작성할 수있는 웹 소켓의 닫기 방법을 사용합니다.

var connection = new WebSocket('ws://127.0.0.1:1337');
    connection.onclose = () => {
            console.log('Web Socket Connection Closed');
        };
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.