...
웹 개발을 처음 배우기 시작했다면 서버와 클라이언트의 통신은 모두 HTTP 프로토콜만 이용해서 이루어진다고 생각할 수 있습니다.
하지만 웹 개발을 하면서 채팅, 게임, 주식 차트 등의 실시간 통신이 필요한 서비스를 구현하려 하면 HTTP 프로토콜이 아닌 웹소켓 프로토콜을 사용하는 것이 좋다는 이야기를 흔히 찾아볼 수 있습니다.
HTTP의 한계
HTTP는 약속입니다. 약속을 영어로 표현하면, 프로토콜이라고 합니다.
HTTP가 등장하기 이전 세대에서 통신한다 함은, 터미널 창에서 딱딱한 텍스트를 주고 받는 것이었어요.
그런데 HTTP가 등장하니, 시각적으로나 정보량 차원에서 엄청나게 멋진 문서를 주고 받을 수 있게 되었습니다.
그런데 HTTP에는 무서운 대전제가 붙습니다.
사용자가 URL을 요청할 때에만! 서버에서 해당 페이지를 꺼내주는 식이라는 겁니다.
거꾸로 말하자면, 사용자는 서버로부터 새로운 정보를 받아보기 위해서, 반드시 새로운 URL을 요청해야 한다는 말과 같습니다.
예를 들어보겠습니다. 공공기관 웹사이트의 회원가입 과정을 떠올려보세요.
즉, 브라우저가 웹서버에 무엇인가를 요청하려면, 페이지를 이동해야만 했습니다.
사실 그렇게 웹페이지를 이동하는 방식으로 만들어버리면 시각적으로 너무 뻣뻣하고 구렸기 때문에 많은 꼼수들이 등장합니다.
액티브엑스도 그 중 하나입니다.
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를 받으면 이어졌던 연결이 끊기게 되어있습니다. 그래서 화면의 내용을 갱신하기 위해서는 다시 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에 큰 부담이 될 수 있습니다.
- 오래된 버전의 웹 브라우저에서는 지원하지 않습니다. (물론 SockJS 라이브러리 같은 경우에는 Fallback option을 제공하고 있습니다.) 참고로 인터넷 익스플로어 같은 경우에는 10 버전부터 지원합니다.
- 서버와 클라이언트 간의 연결이 끊어졌을 때 생성되는 에러 메세지가 구체적이지 않아서 (예를 들어 여러가지 다른 이유로 연결이 끊어졌는데 에러 메세지가 같은 경우) 디버깅을 하는데 어려움이 많기도 합니다.
아무리 좋은 기술이라 할지라도 모든 경우에 유용할 수는 없는 법이기 때문에 프로그램에 꼭 필요한 기술인지 잘 체크하고 수용 여부를 결정하는 것이 바람직합니다.
대표적인 웹소켓 사용 예
- 페이스북 같은 SNS 어플리케이션
- LOL 같은 멀티플레이어 게임들
- 구글 Doc 같이 여러 명이 동시 접속해서 수정할 수 있는 Tool
- 클릭 동향 분석 데이터 어플 (특정 시간동안 어느 사이트에 주로 접속했는지 등의 정보를 파악하는 어플)
- 증권 거래 정보 사이트 및 어플
- 스포츠 업데이트 정보 사이트 및 어플
- 화상 채팅 어플
- 위치 기반 어플
- 온라인 교육 사이트 및 어플
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.