1. WebSockets의 등장과 Node.js의 역할
-
Node.js의 활용: 2009년 말 Node.js의 비동기 이벤트 루프 모델이 WebSockets의 상시 연결 특성과 잘 맞물린다고 판단, 초기 WebSockets 기능 구현에 Node.js를 활용했습니다.
- WebSockets의 특징:
- HTTP와 동일한 포트(80/443) 사용, HTTP 요청으로 시작하여
Upgrade헤더를 통해 WebSockets 연결로 전환. - 연결이 유지(Connection Keep-Alive)되어 TCP와 유사한 상시 연결 제공.
- 프레임 단위 데이터 전송으로 기존 Ajax(폴링)나 Comet(롱 폴링) 방식 대비 오버헤드가 현저히 낮고 효율적입니다.
- HTTP와 동일한 포트(80/443) 사용, HTTP 요청으로 시작하여
- JavaScript API:
WebSocket객체 생성,onopen,onmessage,onclose콜백 함수 설정,send메서드를 통한 데이터 전송 등 매우 단순한 API 구조를 가집니다.
2. WebSockets의 브라우저 지원 및 과제
-
지원 현황: Chromium, Safari 5, Firefox 4 베타 등 주요 브라우저에서 WebSockets가 구현되기 시작했습니다.
-
프로토콜 변화: 초기 드래프트 버전(75, 76) 간의 비호환성으로 기존 라이브러리가 무용지물이 되는 문제가 발생했습니다.
- IE 및 모바일 대응:
- IE는 WebSockets를 직접 지원하지 않으므로, Flash를 이용한 에뮬레이션 라이브러리(예:
web-socket-js)를 통해 호환성을 확보했습니다. - iPhone/iPad는 Flash를 지원하지 않으므로, PhoneGap과 Objective-C를 연동하는 방식으로 우회 구현이 가능합니다.
- IE는 WebSockets를 직접 지원하지 않으므로, Flash를 이용한 에뮬레이션 라이브러리(예:
- 데이터 형식: 초기에는 UTF-8 텍스트 전송이 권장되었으며, 바이너리 전송은 아직 실험적 단계였습니다.
3. Ruby 기반 WebSockets 구현
- Ruby 라이브러리 소개:
EM-Websocket: EventMachine 기반의 라이브러리.Rev-Websocket: Rev 프레임워크 기반의 라이브러리.Cramp: 37signals의 Pratik Naik이 개발한 프레임워크로, 컨트롤러 개념을 도입하고 HTTP 서버와 WebSockets를 통합할 수 있습니다.Rainbows: 다양한 동시성 모델(스레드 풀, 액터)을 전환할 수 있는 유연성을 제공합니다.
- 라이브러리 선택 기준:
- 최신 WebSockets 드래프트 버전(76) 지원 여부.
- 단순 라이브러리 또는 프레임워크 형태(Cramp처럼 HTTP 서버와 통합 가능 여부).
- 성능: EventMachine 기반 라이브러리들은 높은 성능을 보이며, 벤치마크 결과 Node.js와 유사한 수준의 동시 연결 처리 능력을 보여주었습니다.
4. Pusher 아키텍처 및 확장성
-
서비스 모델: 기존 웹 애플리케이션(Rails 등)과 Pusher WebSockets 서버를 분리하여, 클라이언트가 Pusher 서버에 직접 연결하고, 웹 서버는 REST API 호출을 통해 Pusher 서버로 데이터를 푸시하는 방식입니다. 이는 크로스 도메인 WebSockets 연결이 가능하다는 점을 활용합니다.
-
Pusher의 추상화: 단순한 WebSockets API를 보완하기 위해
채널(Channel)및이벤트(Event)개념을 도입하여 특정 채널에 메시지를 보내거나 사용자 정의 이벤트에 바인딩할 수 있도록 했습니다. -
확장성 확보:
- 세션 관리: Redis를 사용하여 세션 ID 룩업 및 관리를 최적화했습니다.
- 서버 간 통신: 여러 Pusher 프로세스 간의 메시지 브로드캐스팅을 위해 RabbitMQ와 같은 메시지 큐 시스템을 활용하여 Pub/Sub 모델을 구현했습니다.
- 프록시 우회: 기업 환경의 방화벽 및 프록시 문제를 해결하기 위해, 80번 포트 연결 실패 시 자동으로 443번 TLS 포트를 사용하여 연결을 시도하는 전략을 채택했습니다.