서버와 클라이언트 간의 메시지 교환을 위한 통신 규약
양방향 통신 (Full-Duplex)
데이터 송수신을 동시에 처리 할 수 있는 방법
통상적인 HTTP 통신은 client가 요청을 보내는 경우에만 Server가 응답하는 단방향 통신
웹 소켓은 양방향 통신이 가능
실시간 네트워킹
웹 환경에서 연속된 데이터를 빠르게 노출하는 것
ex) 체팅, 주식
웹 소켓이 나오기 전
양방향 통신과 실시간 네트워킹 가능하기 한 방법들
네트워크
하나의 장치가 충돌 또는 회피 동기화 처리 목적으로 다른 장치의 상태를 주기적 검사, 일정 조건을 만족시, 송수신의 등 자료 처리 하는 방식
웹
브라우저가 일정한 주기로 HTTP 요청을 보내는 방식
불필요한 서버 및 네트워크 부하가 일어난다는 단점
HTTP 방식은 기본적으로 단방향 통신을 위해 사용된 규약

client가 주기적으로 평범한 Request -> response

Long Polling에 비해 응답마다 다시 요청을 하지 않아도 되므로 효율적,
연결 시간이 길어질 수록 연결 유효성 관리의 부담이 발생
HTTP 통신을 하기 때문에 Request, Response Header 불필요하게 큼

빨간 박스 : Opening HandShake
노란 박스 : Data transfer
보라 박스 : Closing Handshake
REQUEST
GET /chat HTTP/1.1
Host: localhost:8080
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://localhost:9000
연결 수립
ws/wss 프로토콜이 아닌 http/https 프로토콜을 사용
GET
HTTP는 1.1 이상
Host
웹 서버의 주소
Upgrade
프로토콜 전환을 위한 헤더
웹 소켓 요청 시에는 반드시 websocket 값을 부여
해당 헤더가 없거나 다른 값일 경우 cross-protocol attack으로 간주하여 웹 소켓 접속을 중지시킴
Connection
요청 완료 후 네트워크 접속 유지 여부에 대한 정보
Upgrade 헤더가 명시되었을 경우, 요청에는 반드시 Upgrade 옵션을 지정한 Connection 헤더를 같이 명시해야 함
해당 헤더가 없거나 다른 값일 경우 웹 소켓 접속을 중지시킴
Sec-WebSocket-Key
16byte 길이의 임의의 숫자를 base64로 인코딩한 값
클라이언트와 서버 간 인증에 사용
Sec-WebSocket-Protocol
클라이언트가 요청하는 프로토콜들로, 하나 이상의 웹 소켓 프로토콜들을 지정
공백 문자로 구분, 순서에 따라 우선권을 부여
서버에서 각 프로토콜이나 프로토콜 버전에 따라 서비스를 나눌 경우 필요
Origin
클라이언트의 주소
해당 헤더가 없는 경우 요청이 거부될 수 있음 (CORS 정책)
RESPONSE
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
101 Switching Protocols
웹 소켓 연결
Upgrade, Connection
요청과 동일
sec-WebSocket-Accept
Sec-WebSocket-key 값을 unique id 값을 더해서 SHA-1로 해싱한 값을 base64로 인코딩한 결과값
해당 값이 클라이언트에서 계산된 값과 일치해야 연결 수립
SEND DATA
프로토콜이 http/https => ws/wss로 변경
port는 http와 같은 port 사용
클라이언트와 서버는 Message 단위로 데이터를 주고 받으며, Message는 한개 이상 Frame으로 구성
Message : 여러 Frame들이 모여 구성되는 논리적 단위 & Message에는 텍스트 데이터와 이진 데이터만 담길 수 있음
Frame


연결 종료
클라이언트 혹은 서버가 상대방에게 연결 종료를 위한 Close Frame을 전송
요청을 받은 쪽에서 응답으로 Close Frame을 전송하여 Web Socket 연결 종료
데이터 전송에 사용되는 가장 작은 단위의 데이터
헤더 + payload로 구성
텍스트 데이터, 이진 데이터, 컨트롤 프레임 등이 있음
웹 소켓은 HTML5 기술이기 때문에 오래된 버전의 웹 브라우저는 웹 소켓을 지원하지 않음.
이를 해결하기 위해 나온 방법
양방향 통신을 하기 위해 웹 소켓 기술을 활용하는 Node.js 라이브러리.
웹소켓, 폴링, 스트리밍 등 다양한 방법을 하나의 API로 추상화한 것이다.
자바스크립트를 이용하여 브라우저 종류에 상관 없이 실시간 웹을 구현
Http를 사용하면 헨드셰이크를 통해 연결이 설정된 다음 요청 -> 응답 주기에 사용
Http/1.1에서는 동일한 TCP/IP 연결을 여러 요청 -> 응답을 재사용, 오버헤드가 줄어들고 대기 시간은 향상. 단 WebSocket 만큼은 아님. 연결은 몇초에서 몇분 까지 비교적 짧은 시간내에 종료

데이터 전송 및 인코딩
데이터 전송 방법 고려
WebSocket 연결은 전이중 양방향 통신 사용. 즉 연결의 어느 한쪽이 원할 때마다 메시지를 보낼 수 있음
HTTP 연결은 반이중 통신을 사용. 한번에 한쪽만 통신, 서버의 메시지는 항상 클라이언트의 요청에 대한 응답
WebSocket과 HTTP는 모두 JSON, XML, 일반 텍스트와 같은 텍스트 기반 형식으로 인코딩된 데이터와 이진 인코딩 데이터를 보낼 수 있음
오류 및 복구
애플리케이션 코드 오류를 통해 비슷한 다양한 이유로 WebSocket 연결 실패할 가능성.
클라이언트는 수신할 수 있는 오류 이벤트를 전송, 수신자가 적절하다고 판단된느 대로 오류 처리. 그러나 WebSocket 서버가 애플리케이션 코드 내에서 실행 중인 경우 애플리케이션 수준의 치명적 오류는 정상적 오류 처리 구현하는 앱의 기능에 큰 영향
물론 HTTP 연결에서도 비슷한 상황 발생, 특정 공통 아키텍처는 오류 처리와 관련하여 이점 제공.
HTTP는 요청의 성공 여부를 광범위하게 나타내기 위해 서버가 응답할 수 있는 상태코드 범위 지정
*) 4XX ~ 5XX 범위는 각각 클라이언트 및 서버 오류
확장성
WebSocket 연결을 수행하는 작업에서 매우 효율적 설계
이벤트 중심, 메시지를 보낼 내용이 있을 때만 메시지가 전송
HTTP 연결은 롱 폴링을 통해 실시간 기능과 유사하게 달성 가능.
여기서 요청은 응답할 내용이 있을때 까지 보내지고 열리게 됨. 실시간 통신은 대략적인 근사치는 규모적인 부분에서 제약 사항이 있음. HTTP 요청은 무기한 열려 있을 수 없습니다. 즉, 클라이언트는 정기적으로 새로운 긴 폴링 요청을 열어야 합니다. 시간이 지남에 따라 수명이 긴 HTTP 요청을 모두 처리하는 오버헤드가 추가
HTTP 스트리밍을 사용하면 지속적인 데이터 스트림을 촉진하기 위해 연결이 무기한 열린 상태로 유지. 이는 개념적으로 WebSocket과 유사하지만 여전히 HTTP를 통해 수행되며 여전히 단방향
WebSocket과 HTTP 연결 성능 고려 사항
지속적인 연결 덕분에 WebSocket은 오버헤드와 대기 시간이 줄어드는 이점을 누리고 있음. 이를 통해 성능이 향상되고, 실시간 업데이트가 빨라지며, HTTP 3방향 핸드셰이크 및 HTTP 관련 애플리케이션에 소요되는 처리 능력이 줄어든다.