상세 컨텐츠

본문 제목

TIL #46 웹소켓(Web Socket)(Node.js 45일차)

카테고리 없음

by swiming 2024. 6. 25. 21:19

본문

웹소켓

- 사용자의 브라우저와 서버 사이의 동적인 양방향 연결 채널을 구성하는 HTML5 프로토콜이다( WebSocket API를 통해 서버로 메시지를 보내고 요청 없이 응답을 받아오는 것이 가능)

- HTTP는 클라이언트에 의해 초기화되기에 서버가 변경사항을 클라이언트에게 알릴 수 있는 방법이 없지만 WebSocket의 연결은 HTTP 통신과 달리 클라이언트가 특정 주기로 Polling하지 않아도 변경된 사항을 시기 적절하게 전달할 수 있는 지속적이고 완전한 양방향 연결 스트림을 만들어 주는 기술이다

-  Polling(폴링) : 웹소켓 이전에 HTTP 통신(수동적인 반이중통신)으로 양방향처럼 보이도록 계속해서 새로운 업데이트가 있는지 지속적인 요청을 통해서 있다면 가져오는 기존의 방식

- Server Sent Events(서버 센트 이벤트, SSE) : 처음에 한 번만 연결하면 서버가 클라이언트에 지속적으로 데이터를 보낸다. 웹 소켓과의 차이는 클라이언트에서는 서버로 데이터를 보낼 수 없다

- 최초 접속에서만 HTTP 위에서 Hand Shaking을 하기 때문에 HTTP 헤더를 사용

메시지에 포함될 수 있는 교환 가능한 메시지는 텍스트와 바이너리

- WebSocket 연결을 사용하면 데이터가 사용 가능한 즉시 전송(클라이언트의 지속적 요청 필요 없음; 결과적으로 오버헤드와 네트워크 트래픽이 최소화되어 대기 시간이 훨씬 단축된다)

- WebSocket은 서버의 데이터를 클라이언트에 즉시 전달할 수 있는 실시간 애플리케이션 작성에 매우 효과적인 프로토콜로 전이중통신 실시간 네트워킹이 보장되어야 하는 환경에서 유용(채팅, 문의, 알림, 트레이딩 기능 등)

[스택오버플로 발췌]

- http나 https가 아닌 ws, wss 프로토콜을 사용(ws, wss의 차이점은 http, https와 동일)

- 웹 소켓과 HTTP는 같은 포트를 사용할 수 있으므로 따로 포트를 설정할 필요 없다

- 핸드셰이크 과정(소켓 통신이 가능한지 확인하는 절차)

   1) 최초 연결 요청 시 클라이언트에서 HTTP를 통해 웹서버에 요청(이게 핸드셰이크)

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

[

  • GET /chat HTTP/1.1 : 반드시 GET 방식으로만 요청(HTTP 1.1 이상)
  • Host: example.com:8000 : 웹 소켓 서버 주소
  • Upgrade: websocket : 현재 클라이언트, 서버, 전송 프로토콜 연결에서 다른 프로토콜로 업그레이드 또는 변경하기 위한 규칙
  • Connection: Upgrade : 송신자는 반드시 Upgrade 옵션을 지정한 Connection 헤더 필드가 필요
  • Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== : 클라이언트와 서버 간 서로의 신원을 인증
  • Sec-WebSocket-Protocol: chat, superchat : 여러 서브 프로토콜을 의미, 이 중에서 서버가 지원하는 프로토콜을 다시 반환한다.
  • Origin: http://example.com : 클라이언트의 주소]

 

웹소켓 connection 상태

  • CONNECTING: 연결 중
  • OPEN: 열림, 열림일 때만 에러 없이 메시지를 보낼 수 있다.
  • CLOSING: 닫는 중
  • CLOSED: 닫힘

2) 서버에서 웹 소켓 통신이 가능하다면 서버에서 웹 소켓 통신이 가능하다는 101 상태의 응답을 보낸다. 이 때 서버에서는 클라이언트에서 받은 'Sec-WebSocket-Key' 키 값에 문자를 더한 뒤 암호화하여 'Sec-WebSocket-Accept'로 클라이언트로 응답한다

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=[
  • [101 Switching Protocols : 101 Switching Protocols가 응답으로 오면 웹 소켓이 연결되었다는 의미이다.
  • Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=: - 클라이언트로 부터 받은 Sec-WebSocket-Key를 사용하여 계산된 값으로 서로의 신원을 인증하는 과정에 필요한 헤더 - 클라이언트에서 계산한 값과 일치하지 않으면 연결하지 않는다.]

3) 'ws' 혹은 'wss' 프로토콜을 이용해 양방향 통신을 진행

- ws(포트 80) or wss(포트 443) 으로 통신

- 연결이 수립되면 클라이언트와 서버 양측간의 데이터 통신 단계가 시작된다. 서로는 메세지를 보내며 통신하는데, 이 메세지 프레임(Frame) 단위로 이루어진다

- Message : 여러 Frame이모여서 구성하는 하나의 논리적 메시지 단위. ws 프로토콜을 통해 주고 받는 단위

- Frame : Communication에서 가장 작은 단위의 데이터 (작은 헤더 + Payload 로 구성) -> 기존 무거운 헤더의 단점을 보완

- 웹 소켓 통신에 사용되는 데이터는 UTF-8 인코딩을 통해서만 지원

- Heartbeat : 연결 수립 이후에는 서버와 클라이언트는 언제든 상대방에게 ping 패킷을 보낼 수 있다. Ping 을 수신한 측은 가능한 빨리 pong 패킷을 상대방에게 전송해야하고 서로의 연결이 살아있는지를 주기적으로 확인한다

- 0x00{보내고 싶은 데이터}0xff 와 같은 형태로 데이터를 주고 받는다

- 연결 종료 : 연결 종료를 원하는 측이 Close Frame 을 상대쪽으로 전송(클라이언트, 서버 양 쪽 모두 가능)

 

cf) 프레임 구조

 

  • FIN (END) : 이 프레임이 전체 메시지의 끝인지 나타내는 플래그
  • OPCODE
    • Continue (0x0) : 전체 메시지의 일부임을 의미
    • Text (0x1) : 포함된 데이터가 UTF-8 텍스트라는 의미
    • Binary (0x2) : 포함된 데이터가 이진 데이터라는 의미
    • close (0x8) : Close 핸드쉐이크를 시작한다는 의미
  • Length : 이 프레임에 포함된 데이터의 총 길이를 나타내는 단위
  • RSV 1~3 : 프로토콜 별로 사용할 수도 있고 사용할 수도 있지 않은 것들

 

Socket I.O

- 웹 소켓은 HTML5 이후에 나왔기 때문에, HTML5 이전의 기술에는 적용이 어렵다.( 일부 브라우저에서 웹 소켓을 지원하지 않을 때에도 폴백(fallback) 옵션으로 다른 통신 방식을 사용)

- 구현 :

  • socket.io 패키지를 불러와 익스프레스 서버와 연결
  • 연결 후에는 이벤트 리스너를 붙인다. connection 이벤트는 클라이언트가 접속했을 때 발생하고, 콜백으로 소켓 객체(socket)를 제공
  • io와 socket 객체가 Socket.IO의 핵심
  • Socket 객체의 이벤트 리스너 : - disconnect: 클라이언트가 연결을 끊었을 때 발생 - error: 통신 과정에서 에러가 나왔을 때 발생 -reply: 사용자가 직접 만든 이벤트, 클라이언트에서 reply라는 이벤트명으로 데이터를 보낼 때 서버에서 받는 부분
  • Socket.IO도 미들웨어를 사용할 수 있으므로 express-session을 공유하면 된다