티스토리 뷰
간단한 node 웹소켓 예제를 따라 해 보다가,
WebSocket is distinct from HTTP.
Both protocols are located at layer 7 in the OSI model and depend on TCP at layer 4. [위키피디아]
이렇게 웹소켓과 http는 엄연히 다른거라는데
왜 요렇게 http서버로 웹소켓을 만들지?라는 궁금증에 찾아보다가 좋은 글을 발견해서 정리해두려고 한다.
이 글을 기반으로 작성되었습니다. 😎
참고 : https://codeburst.io/polling-vs-sse-vs-websocket-how-to-choose-the-right-one-1859e4e13bd9
두 가지 접근법
(서버로부터 변경사항을 그때 그때 전달받을 수 있는 방법은 없을까? 를 해결할)
기본적으로 HTTP의 통신 방식은 "클라이언트의 요청 후 서버의 응답" 패턴으로 unidirectional (단방향)이다.
서버는 나한테 온 요청의 헤더에 어디서 보냈는지 클라이언트의 주소가 적혀있으니 거기로 다시 답장을 보내는 거지,
아무런 요청 없이 없었는데 누구한테, 주소가 어딘 줄 알고, 먼저 데이터를 보내진 못한다.
그래서 real time web의 구현 방식은 서버로부터 클라이언트로 어떻게 "proactively" 데이터를 전송할 거냐는 고민의 해결 방식과 큰 연관이 있다.
대표적인 두 접근법에는 client pull과 server push가 있다.
이 접근법을 구체적으로 구현한 방식들
Polling
폴링(polling)이란 하나의 장치(또는 프로그램)가 충돌 회피 또는 동기화 처리 등을 목적으로 다른 장치(또는 프로그램)의 상태를 주기적으로 검사하여 일정한 조건을 만족할 때 송수신 등의 자료처리를 하는 방식을 말한다 [위키피디아]
폴링은 클라이언트가 서버에게 새 데이터를 주기적으로 요구하는 방식이다. 두 가지 폴링이 있음.
(1) short polling (AJAX-based timer)
고정된 시간 간격(fixed delay)마다 클라이언트가 서버에 요청을 보냄.
setTimeout으로 일정한 간격마다 ajax요청 보내는 식의 코드로 구현하면 됨.
(2) long polling (Comet)
요청 보내 놓고 기다리다가 응답받으면 처리하고 바로 또 요청 보냄.
(잠깐 🖐)
👩🦰 AJAX
Asynchronous Javascript And Xml
자바스크립트를 사용하여 브라우저가 서버에게 (1) 비동기 방식으로 데이터를 요청하고 서버가 (2) 응답한 데이터를 수신하여(3) 웹페이지를 동적으로 갱신하는 프로그래밍 방식.
Ajax는 브라우저에서 제공하는 Web API인 XMLHttpRequest객체를 기반으로 동작한다. [모던 자바스크립트 - 이웅모 저]
서버에게 요청을 보낼 때 페이지 전체를 리로드 하는 대신,
자바스크립트( XMLHttpRequest객체를 통해 요청하고 JSON이나 XML 형식으로 돌아온 응답을 콜백 함수가 처리 )
를 이용해 처리하고 화면의 바뀐 부분만 다시 렌더링 할 수 있다.
ajax요청은 직접 XMLHttpRequest객체를 이용할 수도 있고, 더 간단히는 jquery.ajax나 다른 라이브러리를 사용할 수도 있다.
★ 어쨌든 ajax도 새 데이터를 위해, 클라이언트 측에서 먼저 요청을 보내는 방식이다!
👩🦰 Comet
(특정 api 제품 명칭 같은 게 아니라 웹앱 모델을 부르는 말. 거의 롱폴링이랑 동의어 느낌으로 쓰이는 것 같다..?)
코멧은 장시간 HTTP 요청을 대기하더라도 브라우저가 명시적으로 요청을 하지 않으면서 웹 서버가 데이터를 브라우저에 푸시할 수 있게 하는 웹 어플리케이션 모델이다.
Comet은 Ajax Push, Reverse Ajax, Two-way-web, HTTP streaming, HTTP server push 등의 명칭으로 불리기도 한다.
[위키피디아]
( 👸다시 본문으로 )
웹소켓
한 번의 TCP 연결을 이용해서 서버 - 클라이언트 간의 연결을 계속 유지하며 full duplex 통신 채널을 제공하는 프로토콜.
(클라이언트) 대부분의 브라우저는 웹소켓 지원하고 (IE는 지원하지 않는다고 함)
(서버) 서버 사이드에서는 socket.io나 ws 같은 패키지를 이용하면 된다.
Socket.io 패키지
웹소켓 연결을 시도하고 (97% 성공률) 실패하면 http 롱폴링 방식 사용하는 패키지라고 함.
웹소켓 패킷에 몇 가지 메타데이터를 덧붙인 형식이므로 일반 웹소켓 서버나 클라이언트와는 잘 연결되지 않을 수 있다.
(socket.io 서버)
npm install socket.io
(socket.io 클라이언트)
html 소스에 <script src="/socket.io/socket.io.js"></script> (혹은 비 브라우저에서 돌릴 때) npm install socket.io-client
That’s all it takes to load the socket.io-client, which exposes an io global
var socket = io();
I’m not specifying any URL when I call io(), since it defaults to trying to connect to the host that serves the page.
참고 : https://socket.io/get-started/chat
https://socket.io/docs/v3/index.html
★ http upgrade header를 가지고 http request, respone를 주고받으면서 기존 연결의 프로토콜이 http에서 websocket으로 교체되며 웹소켓 연결이 시작된다.
그래서 맨 위 예제 코드에서 http가 등장했던 것!
RFC 6455 states that WebSocket “is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries” thus making it compatible with the HTTP protocol
WebSocket handshake uses the HTTP Upgrade header to change from the HTTP protocol to the WebSocket protocol.
If the server supports the WebSocket protocol, it will agree to the upgrade and will communicate this through the Upgrade header in the response
upgrade header
이런 식으로 HTTP1.0에서 HTTP 2.0으로 연결 혹은 HTTP / HTTPS에서 WebSocket으로 기존 연결을 유지한 채
프로토콜을 바꿀 수 있다고 함.
참고 : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Upgrade
다른 분이 잡은 웹소켓 패킷. 참고해보자 : https://blog.naver.com/websearch/221136852414
http vs websocket
참고 : https://www.geeksforgeeks.org/what-is-web-socket-and-how-it-is-different-from-the-http/
SSE (Server Sent Events)
한번 연결이 성립되고 나면, 계속 연결을 유지하면서 서버가 새 데이터 있을 때마다 (별다른 요청 없어도) 브라우저에게 바로 push 할 수 있는 방법이다.
one-way publish-subscribe model으로 불린다.
웹소켓처럼 새로운 프로토콜인 게 아니라 그냥 기존의 HTTP 기반이다. Web API인 EventSource 클래스를 이용한다.
결론
폴링, SSE => HTTP 기반에서, 클라이언트 측 제공 Web API를 이용한 통신방법.
웹소켓 => HTTP와는 별개인 프로토콜. 일단 서버-클라이언트가 HTTP로 연결한 뒤,
HTTP의 프로토콜 업데이트 메커니즘을 이용해 이미 성립된 연결을 websocket 프로토콜로 바꾸어 통신한다.
SSE + (클라이언트 요청은 ajax로) => 주로 (단방향으로) 서버로부터 새로 업데이트되는 (그렇게 용량이 크지 않은) 데이터를 받아보면서 모니터 하는 사이트를 만들 땐 이 방법이 효과적이다.
HTTP 프로토콜을 벗어나지 않고 구현 가능.
예 ) 실시간으로 변동하는 주식차트 정보, SNS 새 피드, 대시보드 업데이트, 날씨, 건강수치 변화 모니터 등..
웹소켓 => 주고받는 데이터 크기가 엄청 크거나, 활발히 양방향으로 통신해야 하는 경우는 웹소켓이 좋다.
예 ) MMORPG 게임
'시리즈 > Web' 카테고리의 다른 글
쿠키, 세션, passport.js (0) | 2021.04.30 |
---|---|
proxy와 CORS 2편 (0) | 2021.04.22 |
proxy와 CORS 1편 (1) | 2021.04.22 |
웹 서버 종류와 WAS (0) | 2021.02.15 |
아주 간단한 웹으로 웹 기본 로직과 http 요청 메소드 이해해보기 (0) | 2021.01.23 |