웹 개발을 처음 배우기 시작했다면 서버와 클라이언트의 통신은 모두 HTTP 프로토콜만 이용해서 이루어진다고 생각할 수 있다.
하지만 웹 개발을 하면서 채팅, 게임, 주식 차트 등의 실시간 통신이 필요한 서비스를 구현하려 하면 HTTP 프로토콜이 아닌 웹소켓 프로토콜을 사용하는 것이 좋다는 이야기를 들어왔을 것이다.
HTTP의 한계
[HTTP] HTTP란?
HTTP(Hyper Text Transfer Protocol)란? HTTP(Hyper Text Transfer Protocol)란 서버-클라이언트 모델을 따르면서 request/response 구조로 웹 상에서 데이터를 주고 받을 수 있는 프로토콜(규칙)이다. TCP/IP 기반으로 작동
s-y-130.tistory.com
HTTP는 약속이다. 약속을 영어로 표현하면, 프로토콜이라고 한다.
HTTP가 등장하기 이전 세대에서 통신한다 함은, 터미널 창에서 딱딱한 텍스트를 주고 받는 것이였다.
하지만 HTTP가 등장하고나서, 시각적으로나 정보량 차원에서 엄청난 문서를 주고 받을 수 있게 되었다.
그런데 HTTP에는 무서운 대전제가 붙는다.
사용자가 URL을 요청할 때에만! 서버에서 해당 페이지를 꺼내주는 식이라는 것이다.
거꾸로 말하자면, 사용자는 서버로부터 새로운 정보를 받아보기 위해서, 반드시 새로운 URL을 요청해야 한다는 말과 같다.
예를 들어보자. 공공기관 웹사이트의 회원가입 과정을 떠올려보자.
즉, 브라우저가 웹서버에 무엇인가를 요청하려면, 페이지를 이동해야만 했다.
사실 그렇게 단순히 웹페이지를 이동하는 방식으로 만들어버리면 시각적으로 재미가 없었기 때문에 많은 꼼수들이 등장한다.
액티브X도 그 중 하나이다.
AJAX 등장
당시에 혜성처럼 등장하기 시작한 구글은 HTTP 규약을 뛰어넘는 방안을 제안한다. 이름하여 AJAX이다.
AJAX는 HTTP를 효과적으로 이용하는 기술이다.
앞에서 HTTP는 약속이라고 말했다. 하지만 AJAX는 약속은 아니다.
단지 효과적으로 서버와 소통하기 위한 기술이다.
그림으로 비교해보자.
다음은 HTTP 에 따른 일반적인 통신 방식이다.
요청 페이지에서 확인을 누르면, 확인을 눌렀다는 정보를 서버에 전달한다.
웹서버는 요청을 받고, 처리한 후에 HTML 페이지를 생성하고, 유저에게 해당 HTML페이지를 전송한다.
이 방식을 선택한다면, HTML(즉 웹 페이지)을 하나 새롭게 브라우저에 뿌리게 되고, 결국 새로운 페이지로 이동하는 결과를 마주하게 된다.
아래는 AJAX 기술이 들어간 통신 방식이다.
AJAX를 쓰면, 유저는 새로운 HTML을 서버로부터 받는 것이 아니다.
즉, 유저는 새로운 웹페이지로 이동하는 것이 아니다. 대신, 동일한 웹페이지 내에서 DOM을 변경하게 된다.
요청 페이지에서 이름 칸에 ‘촉새’를 쓰고, 내용에 ‘안녕하세요. 촉새입니다’라고 썼다고 해보자.
사용자의 이벤트로부터 Javascript는 해당 이름과 내용이 쓰여진 DOM을 읽는다. 그리고는 XMLHttpRequest 객체를 통해 웹서버에 해당 이름과 내용을 전송한다.
웹서버는 요청을 처리하고 XML, Text 혹은 JSON을 XMLHttpRequest 객체에 전송한다. 그러면, Javascript가 해당 응답 정보를 DOM에 쓴다.
그렇게 페이지 이동 없이 결과 페이지가 만들어진다.
즉, AJAX를 쓰면 새로운 HTML을 서버로부터 받아야 하는 것이 아니다. 동일한 페이지의 일부를 수정할 수도 있는 가능성이 생긴 것이다.
결과적으로 사용자 입장에서는 페이지 이동이 발생되지 않고 페이지 내부 변화만 일어나게 된다.
HTML 페이지 전체를 다 바꿔야 하는 것이 아니라 부분만 바꿀 수 있게 되는 것이다.
HTTP vs AJAX
차이1 : 전체를 다 변경해야 하는가? VS 부분만 선별적으로 변경할 수 있는가?
- HTTP는 클라이언트쪽에서 Request를 보내고 Server쪽에서 Response를 받으면 이어졌던 연결이 끊기게 되어있다. (connectionless)
그래서 화면의 내용을 갱신하기 위해서는 다시 request를 하고 response를 하면서 페이지 전체를 갱신하게 된다. - AJAX는 html 페이지 전체가 아닌 일부분만 갱신할수 있도록 XMLHttpRequest객체를 통해 서버에 request 한다. XMLHttpRequest는 서버와의 연결을 잡아둔다. Json이나 xml형태로 필요한 데이터만 주고 받으며 DOM을 갱신하기 때문에 그만큼의 자원과 시간을 아낄 수 있다.
차이2 : 누가 서버에 요청하는가?
- HTTP는 웹브라우저가 서버에 요청한다.
- AJAX는 XMLHttpRequest 객체가 서버에 요청한다.
차이3 : 페이지의 변경사항이 필요할때마다 페이지를 이동하는가?
- HTTP는 항상 페이지를 이동한다.
- AJAX는 조그마한 변경이 필요할 때, 해당 페이지 내에서 변경이 가능하다.
앞서서 HTTP로 회원가입했을 때 중복체크하는 과정과 비교해보자.
AJAX를 쓴다면, 다음과 같은 방식으로 아이디 중복체크하는 것도 가능해진다.
비밀번호 확인, 검색어 실시간 추천, 마우스 커서나 스크롤바 위치에 반응하는 그림, 지도 표시 서비스 등등 다양하다.
그러나 여전히 AJAX로 여전히 수행하지 못하는 것들이 있다.
왜냐하면, AJAX도 여전히 HTTP로 서버와 통신하기 때문이다.
즉, AJAX도 HTTP의 한계를 완전히 벗어나지 못했다.
HTTP는 “클라이언트의 요청이 있고 그 다음 서버로부터 응답을 받는 상황”이라는, 이 틀로부터 벗어나지 못했다.
이러한 경우 외에도 웹 상에서는 갈수록 동적인 표현과 뛰어난 상호작용이 요구되었다.
이러한 문제에 대응하기 위해 Comet 이 등장했다. 하지만, 이 방법은 “클라이언트의 요청이 없음에도, 서버로부터 응답을 받는 상황”에 대한 미봉책이었다.
즉, 데이터 수신을 위해 서버가 클라이언트에게 전송해 주는 푸시(push)방식이 아니라 여전히 클라이언트가 서버에에게 요청하는 폴링(polling) 방식이었다.
이와 같은 애로사항은 HTML5 개발 과정에 녹아들었다. 결국, HTML5은 순수 웹 환경에서 실시간 양방향 통신이 가능해지게 만들어졌다.
그 스펙의 명칭이 바로 웹 소켓(Web Socket) 이다.
※ 참고
AJAX는 이름이 왜 AJAX 인가?
Asynchronous Javascript And Xml의 약자이다. (비동기적인) 자바스크립트로 DOM을 읽고 쓰며, XMLHttpRequest 객체를 통해 서버와 데이터를 주고받기 때문에 명명되어졌다.
※ 참고
HTTP와 HTTPS에는 무슨 차이가 있나?
뒤에 붙은 S는 Secured의 S이다.웹페이지를 요청하는 사람이 무슨 페이지를 요청하는지, 서버가 유저에게 어떤 페이지를 주었는지가 암호화된다. 우리 정부가 불법 웹툰 사이트, 불법 도박 사이트 등을 전부 없애지 못하는 이유도 이 S 때문이다.
웹 소켓 이란?
웹 소켓은 HTML5 표준 기술로, 사용자의 브라우저와 서버 사이의 동적인 양방향 연결 채널을 구성한다.
Websocket API를 통해 서버로 메세지를 보내고, 요청 없이 응답을 받아오는 것이 가능하다.
웹소켓은 매우 단순한 API로 구성되어 있다.
웹소켓을 이용하면 하나의 HTTP 접속으로 양방향 메시지를 자유롭게 주고받을 수 있다.
웹소켓 통신과 비교하면 XmlHttpRequest에서는 통신할 때마다 꼭 요청 헤더가 부여되기 때문에 불과 1바이트의 정보를 송신하고 싶어도 수 킬로바이트에 달하는 쓸데없는 정보를 보내야 한다.
예를 들어, 채팅 입력을 한 문자마다 서버에 송신하고 싶은 경우처럼, 실시간을 추구한 애플리케이션에서는 이 점이 성능 차이로 이어질 가능성이 크다고 할 수 있다.
HTTP vs 웹 소켓 차이점
지금까지 존재했던 통신방법과 WebSocket의 결정적인 차이는 프로토콜에 있다.
WebSocket 프로토콜은 접속 확립에 HTTP를 사용하지만, 그 후의 통신은 WebSocket 독자의 프로토콜로 이루어진다. 또한, header가 상당히 작아 overhead가 적은 특징 이 있다.
장시간 접속을 전제로 하기 때문에, 접속한 상태라면 클라이언트나 서버로부터 데이터 송신이 가능하다.
더불어 데이터의 송신과 수신에 각각 커넥션을 맺을 필요가 없어, 하나의 커넥션으로 데이터를 송수신 할 수 있다.
그리고 통신시에 지정되는 URL은 http://www.sample.com/ 과 같은 형식이 아니라 ws://www.sample.com/ 과 같은 형식이 된다.
WebSocket 소켓이 필요한 경우
- 실시간 양방향 데이터 통신이 필요한 경우.
- 많은 수의 동시 접속자를 수용해야 하는 경우.
- 브라우저에서 TCP 기반의 통신으로 확장해야 하는 경우.
- 개발자에게 사용하기 쉬운 API가 필요할 경우.
- 클라우드 환경이나 웹을 넘어 SOA(Service Oriented Architecture) 로 확장해야 하는 경우
WebSocket 서버의 종류
- pywebsocket(apache)
- phpwebsocket(php)
- jWebSocket(java,javascript)
- web-socket-ruby(ruby)
- Socket.IO(node.js)
Socket.io
그러나 웹소켓은 HTML5의 기술이기 때문에 오래된 버전의 웹 브라우저는 웹소켓을 지원하지 않는다.
특히 자동 업데이트가 되지 않는 익스플로러 구 버전 사용자들은 웹소켓으로 작성된 웹페이지를 볼 수 없다.
따라서 이를 해결하기 위해 나온 여러 기술 중 하나가 Socket.io 이다.
웹페이지가 열리는 브라우저가 웹소켓을 지원하면 웹소켓 방식으로 동작하고, 지원하지 않는 브라우저라면 일반 http를 이용해서 실시간 통신을 흉내내는 것이다.
Socket.io는 node.js 기반으로 만들어진 기술로, 거의 모든 웹 브라우저와 모바일 장치를 지원하는 실시간 웹 애플리케이션 지원 라이브러리이다.
이것은 100% 자바스크립트로 구현되어 있으며, 현존하는 대부분의 실시간 웹 기술들을 추상화해 놓았다.
다시 말해, Socket.io는 자바스크립트를 이용하여 브라우저 종류에 상관없이 실시간 웹을 구현할 수 있도록 한 기술이다.
Socket.io는 웹 브라우저와 웹 서버의 종류와 버전을 파악하여 가장 적합한 기술을 선택하여 사용한다.
만약 브라우저에 FlashSocket이라는 기술을 지원하는 플러그인이 설치되어 있으면 그것을 사용하고 플러그인이 없으면 AJAX Long Polling 방식을 사용하도록 한다.
왜 웹소켓을 사용하는가?
초창기 웹은 단순히 인터넷에 접속한 사용자에게 콘텐츠를 전달하는 역할에 지나지 않았다.
사용자와의 상호작용은 크게 중요하지 않았으며, 정보의 검색 및 열람 수준에 그쳤다.
하지만 웹을 통해 사용자들이 정보를 교환하고 스스로 커뮤니티를 만들어 교류하고자 하는 수요가 늘어나면서 게시판, 블로그 등과 같은 서버와 클라이언트 간의 상호작용을 하는 부분들이 생기기 시작했다.
전형적인 브라우저 렌더링 방식은 HTTP 요청에 대한 HTTP 응답을 받아서 브라우저의 화면을 모두 지우고 받은 내용을 새로 표시하는 방식이었다.
그때 Ajax와 같은 기술이 나타나면서 사용자와 긴밀히 상호작용하는 웹 서비스가 등장하였고 인기를 끌기 시작하였다.
다시 말해, 기존에는 서버와 클라이언트가 실시간으로 상호작용하는 웹 서비스를 개발하기 위해서 숨겨진 프레임을 이용하는 방법이나 Long Polling, Stream 등과 같은 다양한 방법을 사용했었다.
하지만 이 방식은 브라우저가 HTTP 요청을 보내고 웹 서버가 이 요청에 대한 HTTP 응답을 보내는 단방향의 메시지 교환 방식을 유지하는 선에서 구현된 방식이다.
즉, 기존의 방법에 일종의 트릭을 사용한 방법이다. 이 때문에 기존의 웹 기술을 이용하여 실시간 웹 서비스를 만드는 일은 복잡하고 어려웠다.
바로 이러한 불편함과 사용자와 긴밀히 상호작용하는 웹 페이지를 더 쉽게 만들고자 하는 개발자의 요구가 브라우저와 웹 서버 사이의 자유로운 양방향 메시지 송수신 방법으로써 HTML5 표준안의 일부인 웹소켓 API가 등장했다.
사용 방법은 Ajax와 비슷하지만, 개념 면에서 Ajax와 차이를 두고 있다.
- Ajax의 경우는 웹 브라우저에서 데이터를 호출하면 웹 서버에서 호출된 값을 검색, 작성해서 웹 브라우저로 메세지를 보내는 형식의 구조라면,
- 웹소켓의 경우는 웹 브라우저에서 호출해서 데이터를 가져가는 기능을 포함하여 반대로 서버에서 클라이언트를 호출할 수 있는 기능까지 있다.
예시로 채팅프로그램을 만든다고 가정할 때, 우리가 채팅을 서버로 보내는 건 가능하다.
그러나 Ajax로 만든 웹 페이지라면 서버 측에서 클라이언트가 보낼 수가 없다. 대응책으로 10초마다 데이터를 갱신해서 확인할 수 있지만,
대신, 웹소켓은 서버에서도 클라이언트를 인지하는 상태이기에 양방향 통신이 가능하다.
HTML5 웹소켓은 매우 유용한 기술이지만, 브라우저별로 지원하는 웹소켓 버전이 다르며 오래된 브라우저의 경우 아예 지원하지 않는다.
따라서 자바스크립트를 이용하여 브라우저에 상관없이 실시간 웹을 구현할 수 있는 Socket.io를 좀 더 많이 사용하고 있다.
웹소켓 사용의 어려운 점
WebSocket은 사용시 위에 서술한 것과 같은 장점들을 주지만 그에 못지 않는 비용을 지불해야 한다.
아래는 WebSocket 사용 시 발생할 수 있는 어려운 점 또는 문제점들이다.
- 프로그램 구현에 보다 많은 복잡성 초래 :
WebSocket은 HTTP와 달리 Stateful protocol이기 때문에 서버와 클라이언트 간의 연결을 항상 유지해야 하며 만약 비정상적으로 연결이 끊어졌을 때 적절하게 대응해야 한다. 이는 기존의 HTTP 사용 시와 비교했을 때 코딩의 복잡성을 가중시키는 요인이 될 수 있다. - 서버와 클라이언트 간의 Socket 연결을 유지한다는 것 자체가 비용이 드는 일이다. 특히나 트래픽양이 많은 서버 같은 경우에는 CPU에 큰 부담이 될 수 있다.
- 오래된 버전의 웹 브라우저에서는 지원하지 않는다. 참고로 인터넷 익스플로어 같은 경우에는 10 버전부터 지원한다.
- 서버와 클라이언트 간의 연결이 끊어졌을 때 생성되는 에러 메세지가 구체적이지 않아서 (예를 들어 여러가지 다른 이유로 연결이 끊어졌는데 에러 메세지가 같은 경우) 디버깅을 하는데 어려움이 많기도 하다.
아무리 좋은 기술이라 할지라도 모든 경우에 유용할 수는 없는 법이기 때문에 프로그램에 꼭 필요한 기술인지 잘 체크하고 수용 여부를 결정하는 것이 바람직하다.
대표적인 웹소켓 사용 예
- 페이스북 같은 SNS 어플리케이션
- LOL 같은 멀티플레이어 게임들
- 구글 Doc 같이 여러 명이 동시 접속해서 수정할 수 있는 Tool
- 클릭 동향 분석 데이터 어플 (특정 시간동안 어느 사이트에 주로 접속했는지 등의 정보를 파악하는 어플)
- 증권 거래 정보 사이트 및 어플
- 스포츠 업데이트 정보 사이트 및 어플
- 화상 채팅 어플
- 위치 기반 어플
- 온라인 교육 사이트 및 어플
참고