HTML5 websocket - 실시간 양방향 통신

안녕하세요. 이번에는 HTML5에 기능 중 websocket에 대한 이야기를 해볼까 합니다. 



과거 우리는 순수 웹 환경에서 채팅과 같은 실시간 응용프로그램들을 구현하기 위하여 참 많은 노력을 해왔습니다. 이제는 구시대의 전유물이 되어버린 hidden iframe을 통한 재 요청 방법, 이후 Ajax의 등장으로 인해 비동기를 통한 반복 요청, 그 이후 Comet의 등장으로 서버의 데이터를 수신 후에 재 요청을 가능하게 하는 방법 등 실시간을 위한 노력은 계속해서 발전하게 되었습니다. 하지만 위 모든 방식은 공통점은 polling 방식이라는 점입니다. 서버가 클라이언트에게 데이터를 push하는 방식이 아니라 클라이언트가 서버에게 데이터를 요청하는 방식이라는 것입니다. 브라우저가 일정한 시간을 주기로 HTTP요청을 보내는 polling 방식은 실시간 데이터의 업데이트 주기를 예측하기 어려우므로데이터가 변경되던 변하지 않던 요청을 하게 되며 그에 따라 불필요한 서버 요청이 다수 발생하게 됩니다. 이러한 부분을 보완하기 위해 고안된 Comet Long-Polling 방식으로 브라우저가 요청 시 서버가 해당 요청을 일정 시간 동안 대기 시킵니다. 만약 대기 시간 안에 데이터가 업데이트되었다면 클라이언트에게 응답을 보내고 다시 요청을 받는 형태이며 대기 시간이 지난 경우는 응답을 끊고 다시 연결을 맺습니다. 하지만 이 방법도 업데이트가 빈번한 경우 polling에 비해 성능상 이점이 크지 않습니다




출처http://www.ibm.com/developerworks/websphere/techjournal/1008_sampathkumar/1008_sampathkumar.html






HTTP프로토콜은 인터넷 역사상 가장 성공적인 프로토콜이지만 연결을 유지하지 않는 특성으로 인해 효율에 문제를 가지고 있습니다. 하나의 요청을 보내려면 연결을 맺고 요청을 보낸 후 응답을 받고 연결을 끊는 방식으로 동작합니다. 10번의 요청을 보내려면 10번의 연결을 맺고 끊는 과정이 필요하며 모든 요청에 헤더 파일이 중복적으로 들어가기 때문에 낭비가 생길 수 밖에 없는 것입니다. 이러한 문제들을 해결하기 위해 html5에는 websocket protocol이 추가 되었습니다. 웹소켓은 http를 기반으로 하지만 http프로토콜과는 전혀 다른 프로토콜입니다. http를 기반으로 한다는 것의 의미는 웹소켓 연결을 맺는 과정에 http가 개입한다는 의미로 handshake과정이 성공적으로 끝나면 http를 웹소켓 프로토콜로 바꾸는 protocol switching 과정을 진행합니다. 이제 웹소켓을 위한 새로운 소켓이 만들어지고, 이 소켓을 이용해서 통신을 합니다. 웹소켓은 최초 접속을 제외 하고는 헤더 정보를 보내지 않기 때문에 네트워크 비용 측면에서 훨씬 이득이 되며 양방향 통신(full-duplex)통신을 하기 때문에 대기 없이 빠르게 구현 할 수 있습니다. 데이터의 구조는 텍스트와 바이너리 모두 양방향 통신이 가능하며 텍스트의 경우 시작 바이트가 0x00 끝 바이트가 0xFF로 끝나며 UTF-8데이터를 포함할 수 있습니다.  






웹소켓은 정말 막강한 기능이지만 한국에서 직접 적용하기에는 아직 약간의 문제 점이 있습니다. 우리나라의 환경에서는 아직까지는 IE 8 ~ 9를 버릴 수 있는 상황이 아니기 때문입니다아래는 브라우저 별 지원상황을 알려주는 표 입니다



출처 : http://caniuse.com/#feat=websockets


보시면 아시겠지만 IE 9이하 버전 그리고 Android 하위 버전들은 지원이 되질 않습니다. 저희 회사는 이미 웹소켓을 이용하여 한화투자증권과 하나대투증권에 실시간 wts를 구축하였습니다. websocket이 지원되는 환경에서는 websocket을 이용하고 지원되지 않으면 flash를 이용, flash도 이용 불가능한 상황이면 Comet의 long-polling 방식을 이용하여 실시간 처리를 동일한 API를 통해 사용할 수 있도록 처리하였습니다. 






웹소켓을 실제 적용하기 위해서는 서버측에서도 코드 구현이 들어가야 하며 이미 이를 위해 몇몇 솔루션들이 존재 합니다. Atmosphere, netty, node.js, verxt.io, kaazing 등등이 그것입니다. 이중 kaazing만이 전세계에 유일한 유료 솔루션으로 이미 많은 곳에 적용되어 사용되어 있다고 합니다. 어느 한 외국의 블로그에서 각 솔루션과의 성능 비교를 한 자료가 있어 이를 살펴 볼까 합니다. 기본적인 구현 코드와 테스트 상황 등이 상세하게 적혀 있으니 참고 하시면 될 것 같습니다. 



아래의 차트는 한눈에 보기 쉽게 하기 위하여 재 작성 하였습니다. 하단 X축은 연결된 Connection을 의미하여 좌측 Y축은 message를 받은 양 우측 Y측은 초당 처리량을 의미 합니다.



1. Atmosphere


                  ------ messages received                                                                ------ msgs/sec



2. Netty




3. Vertx.io


4. Node.js


 chart 제공 : http://www.webponent.com


실험의 저자는 결국 자바 7기반의 vertx.io를 확장성과 안정성이 뛰어나다는 판단으로 선택을 했습니다. 블로그의 저자의 말대로 유일한 유료 솔루션인 kaazing 의 성능 결과도 보고 싶었으나 무료버전의 한계 때문에 제대로된 테스트를 하지 못해 제외 했다고 합니다. 




참고


New Multi-Channel Dynamic CMS