1. 소개
이 섹션은 비규범적입니다.
웹 애플리케이션이 서버 측 프로세스와 양방향 통신을 유지할 수 있도록 하기 위해, 본 명세는 WebSocket
인터페이스를 소개합니다.
이 인터페이스는 기본 네트워크에 대한 원시 접근을 허용하지 않습니다. 예를 들어, 이 인터페이스를 사용하여 사용자 정의 서버를 통해 메시지를 프록시하지 않고는 IRC 클라이언트를 구현할 수 없습니다.
2. WebSocket 프로토콜 변경
WebSocket
API는 이 언어를 사용합니다. [WSP] [FETCH]
작동 방식은 WebSocket 프로토콜의 "WebSocket 연결 설정" 알고리즘을 Fetch와 통합된 새로운 알고리즘으로 교체하는 것입니다. "WebSocket 연결 설정"은 연결 설정, 핸드셰이크 요청 생성 및 전송, 핸드셰이크 응답 유효성 검사라는 세 가지 알고리즘으로 구성됩니다. 이는 먼저 핸드셰이크를 생성하고, 연결을 설정하며 핸드셰이크를 전송하고, 마지막으로 응답을 유효성 검사하는 Fetch와는 계층이 다릅니다. 이러한 변경 사항을 읽을 때 이를 염두에 두세요.
2.1. 연결
url을 입력으로 WebSocket 연결을 얻으려면, 다음 단계를 실행합니다:
-
host를 url의 host로 설정합니다.
-
port를 url의 port로 설정합니다.
-
resource name을 U+002F (/)로 설정하고, url의 path (비어 있는 문자열 포함)의 문자열을, 있는 경우, U+002F (/)로 서로 구분하여 뒤에 추가합니다.
-
url의 query가 비어 있지 않으면, U+003F (?), 그리고 url의 query를 resource name에 추가합니다.
-
secure를 url의 scheme이 "
http
"인 경우 false로, 그렇지 않으면 true로 설정합니다. -
WebSocket 프로토콜의 섹션 4.1의 첫 번째 단계 집합의 2단계에서 5단계까지의 요구 사항을 따르며, host, port, resource name 및 secure를 전달하여 WebSocket 연결을 설정합니다. [WSP]
-
해당 연결이 설정되었으면 이를 반환하고, 그렇지 않으면 실패를 반환합니다.
속성이 다르고 공유할 수 없지만, WebSocket 연결은 "일반적인" 연결과 매우 유사합니다.
2.2. 초기 핸드셰이크
url, protocols, client을 입력으로 WebSocket 연결을 설정하려면, 다음 단계를 실행합니다:
-
requestURL을 url의 복사본으로 설정하고, url의 scheme이 "
ws
"인 경우 "http
"로, 그렇지 않은 경우 "https
"로 설정합니다.이 scheme 변경은 fetching과 잘 통합되기 위해 필수적입니다. 예를 들어, HSTS는 이 변경 없이 작동하지 않을 것입니다. WebSocket이 별도의 scheme을 가진 데에는 실제 이유가 없으며, 이는 레거시 유물입니다. [HSTS]
-
request를 새로운 request로 설정하고, URL을 requestURL, client를 client, service-workers mode를 "
none
", referrer를 "no-referrer
", mode를 "websocket
", credentials mode를 "include
", cache mode를 "no-store
" , redirect mode를 "error
"로 설정합니다. -
`
Upgrade
`, `websocket
`를 request의 header list에 추가합니다. -
`
Connection
`, `Upgrade
`를 request의 header list에 추가합니다. -
keyValue를 forgiving-base64-encoded되고 isomorphic encoded된, 무작위로 선택된 16바이트 값을 포함하는 nonce로 설정합니다.
무작위로 선택된 값이 바이트 시퀀스 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10이었다면, keyValue는 forgiving-base64-encoded되어 "
AQIDBAUGBwgJCgsMDQ4PEC==
"로, isomorphic encoded되어 `AQIDBAUGBwgJCgsMDQ4PEC==
`로 설정됩니다. -
`
Sec-WebSocket-Key
`, keyValue`를 request의 header list에 추가합니다. -
`
Sec-WebSocket-Version
`, `13
`를 request의 header list에 추가합니다. -
protocols의 각 protocol에 대해, `
Sec-WebSocket-Protocol
`, protocol`을 request의 header list에 결합합니다. -
permessageDeflate를 사용자 에이전트 정의 "
permessage-deflate
" 확장 헤더 값으로 설정합니다. [WSP] -
`
Sec-WebSocket-Extensions
`, permessageDeflate`를 request의 header list에 추가합니다. -
Fetch request를 useParallelQueue를 true로 설정하고, processResponse를 response로 설정하며 다음 단계를 실행합니다:
-
response가 네트워크 오류이거나, 상태가 101이 아니면, WebSocket 연결 실패로 처리합니다.
-
protocols가 비어 있지 않고, 헤더 리스트 값 추출이 `
Sec-WebSocket-Protocol
`과 response의 헤더 리스트를 기준으로 null, 실패, 또는 빈 바이트 시퀀스를 반환하면 WebSocket 연결 실패로 처리합니다.이는 The WebSocket Protocol에서 정의된 헤더 체크와 다릅니다. 이는 클라이언트에서 요청하지 않은 하위 프로토콜에 대해서만 다룹니다. 이는 클라이언트에서 요청했지만 서버에서 인정하지 않은 하위 프로토콜을 다룹니다.
-
The WebSocket Protocol의 섹션 4.1에서 마지막 단계 집합의 2단계에서 6단계까지를 따라 response를 검증합니다. 이는 WebSocket 연결 실패 또는 WebSocket 연결이 설정됨으로 이어집니다.
-
WebSocket 연결 실패와 WebSocket 연결이 설정됨은 The WebSocket Protocol에서 정의됩니다. [WSP]
리다이렉트를 따르지 않으며 이 핸드셰이크가 일반적으로 제한되는 이유는 웹 브라우저 컨텍스트에서 심각한 보안 문제가 발생할 수 있기 때문입니다. 예를 들어, 한 경로에 WebSocket 서버가 있고 다른 경로에 열린 HTTP 리다이렉터가 있는 호스트를 고려해 보십시오. 갑작스럽게, 특정 WebSocket URL을 가진 스크립트가 인터넷상의 모든 호스트와 통신하도록 속일 수 있으며(그리고 잠재적으로 비밀을 공유할 수 있습니다), 심지어 해당 URL이 올바른 호스트명을 가지고 있는지 확인하는 경우에도 말입니다.
3. WebSocket
인터페이스
3.1. 인터페이스 정의
WebSocket
클래스에
대한 Web IDL 정의는 다음과 같습니다:
enum {
BinaryType "blob" ,"arraybuffer" }; [Exposed =(Window ,Worker )]interface :
WebSocket EventTarget {constructor (USVString ,
url optional (DOMString or sequence <DOMString >)= []);
protocols readonly attribute USVString url ; // ready stateconst unsigned short CONNECTING = 0;const unsigned short OPEN = 1;const unsigned short CLOSING = 2;const unsigned short CLOSED = 3;readonly attribute unsigned short readyState ;readonly attribute unsigned long long bufferedAmount ; // networkingattribute EventHandler onopen ;attribute EventHandler onerror ;attribute EventHandler onclose ;readonly attribute DOMString extensions ;readonly attribute DOMString protocol ;undefined close (optional [Clamp ]unsigned short ,
code optional USVString ); // messaging
reason attribute EventHandler onmessage ;attribute BinaryType binaryType ;undefined send ((BufferSource or Blob or USVString )); };
data
각 WebSocket
객체는 url과 연관되며, 이는 URL 레코드입니다.
각 WebSocket
객체는 binary type과 연관되며, 이는 BinaryType
입니다.
초기값은 "blob
"이어야
합니다.
각 WebSocket
객체는 ready state와 연관되며, 이는 연결 상태를 나타내는 숫자입니다. 초기값은 CONNECTING
(0)이어야
합니다. 다음 값들을 가질 수 있습니다:
CONNECTING
(숫자 값 0)-
연결이 아직 설정되지 않았습니다.
OPEN
(숫자 값 1)-
WebSocket 연결이 설정되었으며 통신이 가능합니다.
CLOSING
(숫자 값 2)-
연결이 종료 핸드셰이크를 진행 중이거나
close()
메서드가 호출되었습니다. CLOSED
(숫자 값 3)-
연결이 종료되었거나 열리지 않았습니다.
-
socket = new
WebSocket
(url [, protocols ]) -
새로운
WebSocket
객체를 생성하며, 즉시 연관된 WebSocket 연결을 설정합니다.url은 연결이 설정될 URL을 나타내는 문자열입니다. "
ws
", "wss
", "http
", "https
" 스킴만 허용되며, 다른 스킴은 "SyntaxError
"DOMException
를 발생시킵니다. 프래그먼트를 포함하는 URL은 항상 이러한 예외를 발생시킵니다.protocols는 문자열 또는 문자열 배열입니다. 문자열인 경우, 단일 문자열로 구성된 배열과 동일합니다. 생략된 경우 빈 배열과 동일합니다. 배열의 각 문자열은 하위 프로토콜 이름입니다. 서버가 이러한 하위 프로토콜 중 하나를 선택했다고 보고한 경우에만 연결이 설정됩니다. 하위 프로토콜 이름은 The WebSocket Protocol에서 정의한 `
Sec-WebSocket-Protocol
` 필드 값을 구성하는 요소에 대한 요구 사항을 충족해야 합니다. [WSP] -
socket.send(data)
-
WebSocket 연결을 사용하여 data를 전송합니다. data는 문자열,
Blob
,ArrayBuffer
또는ArrayBufferView
일 수 있습니다. -
socket.close([ code ] [, reason ])
-
code를 WebSocket 연결 종료 코드로, reason을 WebSocket 연결 종료 이유로 선택적으로 사용하여 WebSocket 연결을 종료합니다.
-
socket.url
-
WebSocket 연결을 설정하는 데 사용된 URL을 반환합니다.
-
socket.readyState
-
WebSocket 연결의 상태를 반환합니다. 위에 설명된 값을 가질 수 있습니다.
-
socket.bufferedAmount
-
send()
를 사용하여 큐에 추가되었지만 아직 네트워크로 전송되지 않은 애플리케이션 데이터(UTF-8 텍스트 및 바이너리 데이터)의 바이트 수를 반환합니다.WebSocket 연결이 닫힌 경우, 이 속성의 값은
send()
메서드를 호출할 때마다 증가합니다. (연결이 닫힌 후에도 값은 0으로 재설정되지 않습니다.) -
socket.extensions
-
서버에서 선택한 확장을 반환합니다(있는 경우).
-
socket.protocol
-
서버에서 선택한 하위 프로토콜을 반환합니다(있는 경우). 이는 생성자의 두 번째 인수의 배열 형식과 함께 하위 프로토콜 협상을 수행하는 데 사용할 수 있습니다.
-
socket.binaryType
-
socket의 바이너리 데이터가 스크립트에 노출되는 방식을 나타내는 문자열을 반환합니다:
- "
blob
" -
바이너리 데이터가
Blob
형식으로 반환됩니다. - "
arraybuffer
" -
바이너리 데이터가
ArrayBuffer
형식으로 반환됩니다.
기본값은 "
blob
"입니다. - "
-
socket.binaryType = value
-
바이너리 데이터가 반환되는 방식을 변경합니다.
new
WebSocket(url, protocols)
생성자
단계는 다음과 같습니다:
-
baseURL을 this의 관련 설정 객체의 API 기본 URL로 설정합니다.
-
urlRecord를 URL 파서를 url과 baseURL로 적용한 결과로 설정합니다.
-
urlRecord가 실패한 경우, "
SyntaxError
"DOMException
를 발생시킵니다. -
urlRecord의 scheme이 "
http
"인 경우, urlRecord의 scheme을 "ws
"로 설정합니다. -
그렇지 않고, urlRecord의 scheme이 "
https
"인 경우, urlRecord의 scheme을 "wss
"로 설정합니다. -
urlRecord의 scheme이 "
ws
" 또는 "wss
"가 아닌 경우, "SyntaxError
"DOMException
를 발생시킵니다. -
urlRecord의 fragment가 null이 아닌 경우, "
SyntaxError
"DOMException
를 발생시킵니다. -
protocols이 문자열인 경우, protocols를 해당 문자열만 포함하는 시퀀스로 설정합니다.
-
protocols의 값 중 하나가 중복되거나 The WebSocket Protocol에서 정의한 `
Sec-WebSocket-Protocol
` 필드 값을 구성하는 요소 요구 사항을 충족하지 못하는 경우, "SyntaxError
"DOMException
를 발생시킵니다. [WSP] -
이 단계를 병렬로 실행합니다:
-
urlRecord, protocols, client를 사용하여 WebSocket 연결을 설정합니다. [FETCH]
WebSocket 연결을 설정하는 알고리즘이 실패하면, 이는 WebSocket 연결 실패 알고리즘을 트리거하며, 이는 WebSocket 연결 닫기 알고리즘을 호출하고, 이는 WebSocket 연결이 닫혔음을 설정하며,
close
이벤트를 아래에 설명된 대로 트리거합니다.
-
url
getter의 단계는 this의
url을
직렬화된 형태로 반환하는 것입니다.
readyState
getter의 단계는 this의
ready state를
반환하는 것입니다.
extensions
속성은 초기에는 빈 문자열을 반환해야 합니다. WebSocket 연결이
설정된 후, 값이 아래에 정의된 대로 변경될 수 있습니다.
protocol
속성은 초기에는 빈 문자열을 반환해야 합니다. WebSocket 연결이
설정된 후, 값이 아래에 정의된 대로 변경될 수 있습니다.
close(code, reason)
메서드의 단계는 다음과 같습니다:
-
code가 존재하지만 1000과 같거나 3000에서 4999 사이(포함)인 정수가 아닌 경우 "
InvalidAccessError
"DOMException
를 발생시킵니다. -
reason이 존재한다면, 다음 하위 단계를 실행합니다:
-
reasonBytes를 UTF-8 인코딩된 reason의 결과로 설정합니다.
-
reasonBytes가 123 바이트보다 길다면 "
SyntaxError
"DOMException
를 발생시킵니다.
-
-
다음 목록에서 첫 번째로 일치하는 단계를 실행합니다:
- this의 ready state가
CLOSING
(2) 또는CLOSED
(3)인 경우 -
아무것도 하지 않습니다.
연결이 이미 종료 중이거나 종료되었습니다. 아직 발생하지 않은 경우,
close
이벤트가 결국 아래에 설명된 대로 발생할 것입니다. - WebSocket 연결이 아직 설정되지 않았으면 [WSP]
-
WebSocket 연결 실패를 실행하고 this의 ready state를
CLOSING
(2)로 설정합니다. [WSP]WebSocket 연결 실패 알고리즘은 WebSocket 연결 닫기 알고리즘을 호출하며, 이는 WebSocket 연결이 닫혔음을 설정하고,
close
이벤트를 아래에 설명된 대로 발생시킵니다. - WebSocket 종료 핸드셰이크가 아직 시작되지 않았으면 [WSP]
-
WebSocket 종료 핸드셰이크 시작을 실행하고 this의 ready state를
CLOSING
(2)로 설정합니다. [WSP]code와 reason이 모두 없는 경우, WebSocket Close 메시지에는 본문이 없어야 합니다.
The WebSocket Protocol은 WebSocket 종료 핸드셰이크 시작 알고리즘의 상태 코드가 필수라고 잘못 기술하고 있습니다.
code가 존재한다면, WebSocket Close 메시지에서 사용할 상태 코드는 code에 의해 제공된 정수여야 합니다. [WSP]
reason 또한 존재한다면, reasonBytes는 상태 코드 이후 Close 메시지에 제공되어야 합니다. [WSP]
WebSocket 종료 핸드셰이크 시작 알고리즘은 결국 WebSocket 연결 닫기 알고리즘을 호출하며, 이는 WebSocket 연결이 닫혔음을 설정하고,
close
이벤트를 아래에 설명된 대로 발생시킵니다. - 그 외의 경우
-
this의 ready state를
CLOSING
(2)로 설정합니다.WebSocket 종료 핸드셰이크가 시작되며, 이는 결국 WebSocket 연결 닫기 알고리즘을 호출하고, 이는 WebSocket 연결이 닫혔음을 설정하며, 따라서
close
이벤트가 발생합니다. 아래에 설명된 대로.
- this의 ready state가
close()
메서드는 WebSocket 종료 핸드셰이크를 시작하기 전에 이전에 전송된 메시지를 폐기하지 않습니다. 실제로 사용자 에이전트가 여전히 해당 메시지를 전송 중이더라도 핸드셰이크는 메시지 전송이
완료된 후에만 시작됩니다.
bufferedAmount
getter의 단계는 send()
를
사용하여 큐에 추가되었지만, 이벤트
루프가 마지막으로 1단계에 도달했을 때까지
네트워크에 전송되지 않은 애플리케이션 데이터(UTF-8 텍스트 및 바이너리 데이터)의 바이트 수를 반환하는 것입니다. (따라서 현재 작업 실행 중에 전송된 텍스트도 포함되며, 사용자 에이전트가
스크립트 실행과 병렬로 백그라운드에서 텍스트를 전송할 수 있는지 여부와 상관없이 포함됩니다.) 이는 프로토콜에 의해 발생하는 프레임 오버헤드나 운영
체제 또는 네트워크 하드웨어에 의해 수행되는 버퍼링은 포함하지 않습니다.
이 간단한 예제에서 bufferedAmount
속성은 네트워크가 해당 속도를 처리할 수 있는 경우 50ms마다 한 번 업데이트를 전송하거나, 해당 속도가 너무 빠른 경우 네트워크가 처리할 수 있는 속도로 전송되도록 사용됩니다.
var socket= new WebSocket( 'ws://game.example.com:12010/updates' ); socket. onopen= function () { setInterval( function () { if ( socket. bufferedAmount== 0 ) socket. send( getUpdateData()); }, 50 ); };
bufferedAmount
속성은 네트워크가 처리할 수 있는 속도를 초과하지 않으면서 네트워크를 포화 상태로 만드는 데에도 사용할 수 있지만, 이 경우 속성 값의 변화를 신중히 모니터링해야 합니다.
binaryType
getter의 단계는 this의
binary type을
반환하는 것입니다.
binaryType
setter의 단계는 this의 binary type을
주어진 값으로 설정하는 것입니다.
사용자 에이전트는 binary type을 수신된 바이너리 데이터를 처리하는 힌트로 사용할 수 있습니다. 예를 들어, "blob
"인
경우 데이터를 디스크에 저장하는 것이 안전하며, "arraybuffer
"인
경우 데이터를 메모리에 유지하는 것이 더 효율적일 가능성이 높습니다. 물론 사용자 에이전트는 수신된 데이터를 메모리에 유지할지 여부를 결정하기 위해 더 미세한 휴리스틱을 사용하는 것이
권장됩니다. 예를 들어 데이터 크기나 스크립트가 마지막 순간에 속성을 변경하는 경우의 빈도 등을 기준으로 판단할 수 있습니다. 특히 이 마지막 측면은 사용자 에이전트가 데이터를 수신한 후
이벤트를 발생시키기 전에 속성이 변경될 가능성이 높기 때문에 중요합니다.
send(data)
메서드의 단계는 다음과 같습니다:
-
this의 ready state가
CONNECTING
이면, "InvalidStateError
"DOMException
를 발생시킵니다. -
다음 목록에서 적절한 단계를 실행합니다:
- data가 문자열인 경우
-
WebSocket 연결이 설정되었으며 WebSocket 종료 핸드셰이크가 아직 시작되지 않았으면, 사용자 에이전트는 텍스트 프레임 opcode를 사용하여 WebSocket 메시지를 전송해야 합니다. 데이터가 전송될 수 없는 경우(예: 버퍼링이 필요하지만 버퍼가 가득 찬 경우) 사용자 에이전트는 WebSocket을 가득 참으로 플래그하고 WebSocket 연결을 닫아야 합니다. 이 메서드가 문자열 인수를 사용하여 호출되었으나 예외를 발생시키지 않는 경우, 인수를 UTF-8로 표현하는 데 필요한 바이트 수만큼
bufferedAmount
속성을 증가시켜야 합니다. [UNICODE] [ENCODING] [WSP] - data가
Blob
객체인 경우 -
WebSocket 연결이 설정되었으며, WebSocket 종료 핸드셰이크가 아직 시작되지 않았으면, 사용자 에이전트는 바이너리 프레임 opcode를 사용하여 WebSocket 메시지를 전송해야 합니다. 데이터가 전송될 수 없는 경우(예: 버퍼링이 필요하지만 버퍼가 가득 찬 경우) 사용자 에이전트는 WebSocket을 가득 참으로 플래그하고 WebSocket 연결을 닫아야 합니다. 전송할 데이터는
Blob
객체가 나타내는 원시 데이터입니다. 예외를 발생시키지 않는Blob
인수를 사용하여 이 메서드를 호출하는 경우bufferedAmount
속성이Blob
객체의 원시 데이터 크기(바이트 단위)만큼 증가해야 합니다. [WSP] [FILEAPI] - data가
ArrayBuffer
인 경우 -
WebSocket 연결이 설정되었으며, WebSocket 종료 핸드셰이크가 아직 시작되지 않았으면, 사용자 에이전트는 바이너리 프레임 opcode를 사용하여 WebSocket 메시지를 전송해야 합니다. 데이터가 전송될 수 없는 경우(예: 버퍼링이 필요하지만 버퍼가 가득 찬 경우) 사용자 에이전트는 WebSocket을 가득 참으로 플래그하고 WebSocket 연결을 닫아야 합니다. 전송할 데이터는
ArrayBuffer
객체가 나타내는 버퍼에 저장된 데이터입니다. 예외를 발생시키지 않는ArrayBuffer
인수를 사용하여 이 메서드를 호출하는 경우bufferedAmount
속성이ArrayBuffer
길이(바이트 단위)만큼 증가해야 합니다. [WSP] - data가
ArrayBufferView
인 경우 -
WebSocket 연결이 설정되었으며, WebSocket 종료 핸드셰이크가 아직 시작되지 않았으면, 사용자 에이전트는 바이너리 프레임 opcode를 사용하여 WebSocket 메시지를 전송해야 합니다. 데이터가 전송될 수 없는 경우(예: 버퍼링이 필요하지만 버퍼가 가득 찬 경우) 사용자 에이전트는 WebSocket을 가득 참으로 플래그하고 WebSocket 연결을 닫아야 합니다. 전송할 데이터는
ArrayBuffer
객체의 버퍼에서 data가 참조하는 섹션에 저장된 데이터입니다. 예외를 발생시키지 않는 이 유형의 인수를 사용하여 이 메서드를 호출하는 경우bufferedAmount
속성이 data 버퍼 길이(바이트 단위)만큼 증가해야 합니다. [WSP]
다음은 이벤트 핸들러(및 해당 이벤트 핸들러 이벤트 유형)로,
이벤트 핸들러 IDL 속성으로 구현하는
WebSocket
인터페이스를 구현하는 모든 객체에서 지원해야 합니다:
이벤트 핸들러 | 이벤트 핸들러 이벤트 유형 |
---|---|
onopen
| open
|
onmessage
| message
|
onerror
| error
|
onclose
| close
|
4. 프로토콜에서의 피드백
WebSocket 연결이 설정되었을 때, 사용자 에이전트는 작업을 대기열에 추가하여 다음 단계를 실행해야 합니다:
-
ready state를
OPEN
(1)으로 변경합니다. -
extensions
속성 값을 사용 중인 확장으로 변경합니다. 단, null 값이 아닌 경우에만 해당합니다. [WSP] -
protocol
속성 값을 사용 중인 하위 프로토콜로 변경합니다. 단, null 값이 아닌 경우에만 해당합니다. [WSP]
위 알고리즘은 작업으로 대기열에 추가되므로, WebSocket 연결이
설정되는 것과 스크립트가 open
이벤트에 대한 이벤트 리스너를 설정하는 것 사이에 경쟁 조건이 없습니다.
WebSocket 메시지가 수신되었을 때, 해당 메시지의 유형 type과 데이터 data가 함께 사용자 에이전트는 작업을 대기열에 추가하여 다음 단계를 실행해야 합니다: [WSP]
-
ready state가
OPEN
(1)이 아니면, 반환합니다. -
dataForEvent를 type 및 binary type에 따라 결정합니다:
- type이 데이터가 텍스트임을 나타내는 경우
-
data를 포함하는 새
DOMString
- type이 데이터가 바이너리임을 나타내고 binary type이
"blob"
인 경우 -
data를 원시 데이터로 나타내는 새
Blob
객체, 해당WebSocket
객체의 관련 Realm에서 생성됨 [FILEAPI] - type이 데이터가 바이너리임을 나타내고 binary type이
"arraybuffer"
인 경우 -
data를 포함하는 새
ArrayBuffer
객체, 해당WebSocket
객체의 관련 Realm에서 생성됨
-
이벤트를 발생시키며, 이벤트 이름은
message
이고,WebSocket
객체에서 발생하며,MessageEvent
를 사용하고,origin
속성은WebSocket
객체의 url의 origin의 직렬화로 초기화되며,data
속성은 dataForEvent로 초기화됩니다.
사용자 에이전트는 작업을 실행하기 전에 위 단계를 효율적으로 수행할 수 있는지 확인하도록 권장되며, 준비 중인 버퍼와 관련하여 다른 작업 대기열에서 작업을 선택할 수 있습니다. 예를 들어, 데이터가 도착했을 때 binary type이 "blob
"인
경우 사용자 에이전트가 데이터를 디스크로 스풀링했지만, 위와 같은 특정 메시지의 작업을 실행하기 바로 전에 스크립트가 binary
type을 "arraybuffer
"로
변경한 경우, 사용자 에이전트는 해당 작업을 실행하기 전에 데이터를 RAM으로 다시 페이지 처리하는 것이 좋으며, 이는 ArrayBuffer
객체를 생성하는 동안 메인 스레드가 멈추는 것을 방지하기 위함입니다.
다음은 텍스트 프레임의 경우 message
이벤트에 대한 핸들러를 정의하는 예제입니다:
mysocket. onmessage= function ( event) { if ( event. data== 'on' ) { turnLampOn(); } else if ( event. data== 'off' ) { turnLampOff(); } };
여기서 프로토콜은 매우 단순하며, 서버는 단순히 "on" 또는 "off" 메시지를 전송합니다.
WebSocket 종료 핸드셰이크가 시작되었을 때, 사용자 에이전트는 작업을 대기열에 추가하여 ready state를 CLOSING
(2)으로 변경해야 합니다. (close()
메서드가 호출된 경우, 이 작업이 실행될 때 ready state는 이미 CLOSING
(2)으로 설정되어 있을 것입니다.) [WSP]
WebSocket 연결이 닫혔을 때, 깨끗하게 닫혔을 수도 있고(cleanly), 사용자 에이전트는 작업을 대기열에 추가하여 다음 하위 단계를 실행해야 합니다:
-
ready state를
CLOSED
(3)으로 변경합니다. -
사용자 에이전트가 WebSocket 연결 실패를 수행해야 했거나, WebSocket 연결이 닫혔을 때 가득 참으로 플래그된 경우 이벤트를 발생시키며, 이벤트 이름은
error
이고,WebSocket
객체에서 발생합니다. [WSP] -
이벤트를 발생시키며, 이벤트 이름은
close
이고,WebSocket
객체에서 발생하며,CloseEvent
를 사용하고,wasClean
속성은 연결이 cleanly 닫혔을 경우 true로, 그렇지 않을 경우 false로 초기화되며,code
속성은 WebSocket 연결 닫기 코드로 초기화되고,reason
속성은 BOM 없이 UTF-8 디코딩을 WebSocket 연결 닫기 이유에 적용한 결과로 초기화됩니다. [WSP]
사용자 에이전트는 스크립트가 다음 상황을 구별할 수 있는 방식으로 실패 정보를 전달해서는 안 됩니다:
-
호스트 이름을 확인할 수 없는 서버.
-
패킷을 성공적으로 라우팅할 수 없는 서버.
-
지정된 포트에서 연결을 거부한 서버.
-
TLS 핸드셰이크를 올바르게 수행하지 못한 서버(예: 서버 인증서를 확인할 수 없음).
-
초기 핸드셰이크를 완료하지 않은 서버(예: WebSocket 서버가 아니기 때문).
-
올바른 초기 핸드셰이크를 전송했지만 클라이언트가 연결을 끊도록 설정한 옵션을 지정한 WebSocket 서버(예: 서버가 클라이언트가 제공하지 않은 하위 프로토콜을 지정함).
-
초기 핸드셰이크를 성공적으로 완료한 후 연결을 갑자기 닫은 WebSocket 서버.
이 모든 경우, WebSocket 연결 닫기 코드는 WebSocket Protocol에 의해 요구되는 대로 1006이어야 합니다. [WSP]
스크립트가 이러한 경우를 구별할 수 있도록 허용하면 공격 준비를 위해 사용자의 로컬 네트워크를 탐지할 수 있도록 허용할 수 있습니다.
특히, 이는 코드 1015가 사용자 에이전트에 의해 사용되지 않음을 의미합니다(물론 서버가 닫기 프레임에서 이를 잘못 사용하는 경우는 제외합니다).
이 섹션에서 대기열에 추가된 모든 작업의 작업 소스는 WebSocket 작업 소스입니다.
5. 핑 및 퐁 프레임
WebSocket 프로토콜은 keep-alive, 하트비트, 네트워크 상태 탐색, 지연 시간 측정 등을 위해 사용할 수 있는 Ping 및 Pong 프레임을 정의합니다. 현재 API에서는 이를 노출하지 않습니다.
사용자 에이전트는 원하는 경우 Ping 및 요청되지 않은 Pong 프레임을 보낼 수 있습니다. 예를 들어, 로컬 네트워크 NAT 매핑을 유지하거나 실패한 연결을 감지하거나 사용자에게 지연 시간 메트릭을 표시하려는 시도에서 이를 사용할 수 있습니다. 사용자 에이전트는 서버를 지원하기 위해 Ping 또는 요청되지 않은 Pong을 사용해서는 안 됩니다. 서버는 서버의 필요에 따라 적절한 시기에 Pong을 요청할 것으로 가정합니다.
6. CloseEvent
인터페이스
WebSocket
객체는 CloseEvent
인터페이스를 close
이벤트에 사용합니다:
[Exposed =(Window ,Worker )]interface :
CloseEvent Event {(
constructor DOMString ,
type optional CloseEventInit = {});
eventInitDict readonly attribute boolean wasClean ;readonly attribute unsigned short code ;readonly attribute USVString reason ; };dictionary :
CloseEventInit EventInit {boolean =
wasClean false ;unsigned short = 0;
code USVString = ""; };
reason
- event .
wasClean
-
연결이 정상적으로 종료된 경우 true를 반환하고, 그렇지 않으면 false를 반환합니다.
- event .
code
-
서버에서 제공한 WebSocket 연결 종료 코드를 반환합니다.
- event .
reason
-
서버에서 제공한 WebSocket 연결 종료 이유를 반환합니다.
wasClean
속성은 초기화된 값을 반환해야 합니다. 이는 연결이 정상적으로 종료되었는지 여부를
나타냅니다.
code
속성은 초기화된 값을 반환해야 합니다. 이는 서버에서 제공한 WebSocket 연결 종료 코드를
나타냅니다.
reason
속성은 초기화된 값을 반환해야 합니다. 이는 서버에서 제공한 WebSocket 연결 종료
이유를 나타냅니다.
7. 가비지 컬렉션
WebSocket
객체의 ready
state가 마지막으로 이벤트
루프가 1단계에 도달했을 때 CONNECTING
(0)로 설정된 상태라면, open
이벤트, message
이벤트, error
이벤트, 또는 close
이벤트에 대한 이벤트 리스너가 등록되어 있는 경우 가비지 컬렉션되지 않아야 합니다.
WebSocket
객체의 ready
state가 마지막으로 이벤트
루프가 1단계에 도달했을 때 OPEN
(1)로 설정된 상태라면, message
이벤트, error
,
또는 close
이벤트에 대한 이벤트 리스너가 등록되어 있는 경우 가비지 컬렉션되지 않아야 합니다.
WebSocket
객체의 ready
state가 마지막으로 이벤트
루프가 1단계에 도달했을 때 CLOSING
(2)로 설정된 상태라면, error
또는 close
이벤트에 대한 이벤트 리스너가 등록되어 있는 경우 가비지 컬렉션되지 않아야 합니다.
WebSocket
객체가 전송 대기 데이터가 있는 설정된 연결 상태라면 가비지
컬렉션되지 않아야 합니다.
[WSP]
만약 WebSocket
객체가 연결이 여전히 열려 있는 동안 가비지 컬렉션된다면, 사용자 에이전트는 WebSocket
종료 핸드셰이크를 시작해야 하며, Close 메시지에 대한 상태 코드는 없어야 합니다. [WSP]
만약 사용자 에이전트가 사라지게 해야 한다는
WebSocket
객체(이는 Document
객체가 사라질 때 발생합니다)라면, 사용자 에이전트는 다음 목록에서 첫 번째로 적절한 단계를 따라야 합니다:
- WebSocket 연결이 아직 설정되지 않았다면 [WSP]
-
WebSocket 연결 실패를 수행합니다. [WSP]
- WebSocket 종료 핸드셰이크가 아직 시작되지 않았다면 [WSP]
-
WebSocket 종료 핸드셰이크를 시작하며, WebSocket Close 메시지에 사용할 상태 코드는 1001로 설정합니다. [WSP]
- 그 외의 경우
-
아무것도 하지 않습니다.
감사의 글
2021년에 이 표준이 작성되기 전까지, 여기의 내용은 HTML 표준과 Fetch 표준에서 관리되었습니다. 명세 개발에 도움을 준 해당 저장소의 모든 기여자들, 특히 각각의 원저자인 Ian Hickson과 Anne van Kesteren에게 감사드립니다.
WebSockets 표준이 만들어진 이후의 기여에 대해 devsnek과 평야유 (Yutaka Hirano) 에게 감사드립니다.
이 표준은 Adam Rice (Google, ricea@chromium.org)가 작성하였습니다.
지적 재산권
저작권 © WHATWG (Apple, Google, Mozilla, Microsoft). 이 작업은 크리에이티브 커먼즈 저작자표시 4.0 국제 라이선스에 따라 라이선스가 부여됩니다. 소스 코드에 통합된 부분이 있는 경우, 해당 부분은 BSD 3-Clause 라이선스에 따라 소스 코드 내에서 라이선스가 부여됩니다.
이것은 현행 표준입니다. 특허 검토 버전에 관심이 있는 분들은 현행 표준 검토 초안을 확인하시기 바랍니다.