WebSocket

QT-HH·2022년 2월 16일
1

JavaScript

목록 보기
2/5

서버와 브라우저 간 연결을 유지한 상태로 데이터를 교환할 수 있다.

WebSocket

WebSocket 객체는 서버와의 WebSocket 연결을 생성하고 관리할 수 있는 API들을 제공한다.

WebSocket 생성자는 하나의 필수 파라미터와, 하나의 옵셔널 파라미터를 받는다.

WebSocket WebSocket(
  in DOMString url,
  in optional (DOMString or DOMString[]) protocols
)
  • url
    • 연결할 url 주소
  • protocols (optional)
    • 단일 프로토콜 문자열 or 문자열의 배열
    • 이 문자열들은 서브 프로토콜을 지정하는데 사용된다.
    • 하나의 웹소켓 서버가 여러 개의 웹 소켓 서브 프로토콜을 구현할 수 있도록 해준다.
    • 지정하지 않으면 빈 문자열을 넣은 것으로 간주된다.

예시

let socket = new WebSocket("ws://javascript.info");

ws, wss라는 특수 프로토콜을 사용한다.
둘의 관계는 http, https와 유사하다.

웹 소켓 연결 과정

  1. new WebSocket(url)을 통해 소켓을 생성하면서 즉시 연결 시작
  2. 최초에 HTTP 프로토콜로 웹소켓 연결 요청
  • GET /chat
    Host: javascript.info
    Origin: https://javascript.info
    Connection: Upgrade
    Upgrade: websocket
    Sec-WebSocket-Key: Iv8io/9s+lYFgZWcXczP8Q==
    Sec-WebSocket-Version: 13
  • origin: 클라이언트 오리진
  • Connection: 클라이언트 측에서 프로토콜 변경요청
  • Upgrade: 클라이언트측에서 요청한 프로토콜이 “websocket”이다.
  1. HTTP 프로토콜로 연결확인 응답
  • 101 Switching Protocols
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Accept: hsBlbuDTkk24srzEOTBUlZAlC2g=
  1. ws/wss프로토콜로 연결



Methods

close()

연결 혹은 연결 시도를 종료한다. 연결이 끊어진 상태에서는 아무 동작도 하지 않는다.

void close(
  in optional unsigned short code,
  in optional DOMString reason
)
  • code (optional)
    • 연결이 종료되는 이유를 가리키는 숫자
    • Default = 1000 (일반적인 경우의 트랜잭션 완료를 나타내는 값)
  • reason (optional)
    • 연결이 왜 종료되는지를 나타내는 문자열 (일종의 메시지)
    • UTF-8
    • 123바이트를 넘을 수 없음

send()

웹 소켓 연결을 통해 데이터를 서버로 전송

void send(
  in DOMString data
)

void send(
  in ArrayBuffer data
)

void send(
  in Blob data
)
  • data
    • 서버로 전송할 텍스트 메시지
    • 데이터 종류에 따라 특별히 무언가를 세팅해줄 필요가 없다.



Attribute

  • binaryType
    • 전송된 데이터의 바이너리 타입 (“blob” (default)/ “arraybuffer”)
  • bufferedAmount (read only)
    • send()를 호출해서 작업 queue에 들어갔지만 아직 네트워크로 전송이 되지 않은 데이터의 바이트 수
    • 연결이 끊길 때 0으로 초기화되지 않는다.
    • 이 값을 이용해서 네트워크연결이 잘 안될 때 계속해서 데이터 전송하는 것을 막을 수 있다.
    • // 100ms에 한번씩 조건에 따라 send()를 호출한다.
      // send()로 데이터 전송을 요청했지만 네트워크에 전달되지 않은 데이터가 있을 때는 아무런 동작도 하지 않는다.
      setInterval(() => {
        if (socket.bufferedAmount == 0) {
          socket.send(moreData());
        }
      }, 100);```
  • extensions
    • 서버에 의해 선택된 확장기능
    • 데이터 요청 헤더에 Sec-WebSocket-Extensions가 브라우저에 의해 자동으로 생성되어 들어간다.
    • 서버는 헤더를 보고 지원하는 extensions를 선택해서 같은 이름의 헤더로 응답해준다.
  • protocol
    • 서버에 의해 선택된 서브 프로토콜
    • 웹소켓 객체를 생성할 때 원하는 서브 프로토콜을 파라미터에 넣는다.
    • 데이터 요청 헤더에 Sec-WebSocket-Protocol라는 이름으로 요청한 서브 프로토콜들이 들어간다.
    • 서버는 헤더를 보고 지원하는 프로토콜을 선택해서 같은 이름의 헤더로 응답해준다.
  • onclose
    • WebSocket 인터페이스의 연결상태가 readyState에서 CLOSED로 바뀌었을 때 호출되는 이벤트 리스너
  • onopen
    • WebSocket 인터페이스의 연결상태가 readyState에서 OPEN으로 바뀌었을 때 호출되는 이벤트 리스너
  • onerror
    • 에러 이벤트 발생시 처리할 핸들러
  • onmessage
    • 메시지 이벤트 발생시 처리할 핸들러
    • 서버로부터 메시지 도착시 호출
  • url (read only)
    • 생성자에 의해 해석된 URL
    • 항상 절대주소를 가리킨다.
  • readyState (read only)
    • 연결의 현재 상태

readyState

ConstantValueDescription
CONNECTING0연결이 수립되지 않은 상태
OPEN1연결이 수립되어 데이터 교환이 가능한 상태
CLOSING2연결이 닫히는 중
CLOSED3연결이 종료되었거나 연결에 실패


데이터 교환

웹 소켓은 ‘프레임(frame)'이라는 데이터 조각을 사용해 이루어진다. 프레임은 서버와 클라이언트 양측 모두에서 보낼 수 잇는데 프레임 내 담긴 데이터 종류에 따라 다음과 같이 분류할 수 있다.

  • text frame : 텍스트 데이터가 담긴 프레임
  • inary data frame : 이진 데이터가 담긴 프레임
  • ping/pong frame : 연결이 유지되고 있는지 확인할 때 사용하는 프레임. 서버나 브라우저에서 자동생성하여 보낸다.

브라우저 환경에서는 텍스트, 이진 프레임만 다룬다.

데이터 전송

socket.send(body)

body에는 문자열이나 Blob, ArrayBuffer등의 이진 데이터만 들어갈 수 있다.
데이터의 종류에 따라 특별히 무언가 세팅을 해줘야 할 필요는 없다.

데이터 수신

텍스트 데이터는 항상 문자열 형태로 온다.
이진 데이터를 받을 땐 binaryType 프로퍼티를 사용해서 Blob이나 ArrayBuffer포맷 둘 중 하나를 고를 수 있다.
binaryType의 default값이 "blob"이므로 이진 데이터는 기본적으로 Blob형태로 받게 된다.

socket.binaryType = "arraybuffer"
socket.onmessage = (event) => {
  const myData = event.data
  // event.data는 텍스트인 경우 문자열,
  // 이진 데이터인 경우 arraybuffer
  }


참고

profile
FE 초짜

0개의 댓글