Outsider's Dev Story

Stay Hungry. Stay Foolish. Don't Be Satisfied.
RetroTech 팟캐스트 44BITS 팟캐스트

[node.js] 리얼타임 웹을 위한 크로스브라우저 웹소켓 : Socket.IO

제가 소속되어 있는 Front-end 개발자 모임인 FRENDS에서 오프라인으로 발표모임을 진행하고 있는데 지난주 토요일(23일)이 두번째 발표모임이었습니다. 어느정도 정기적으로 진행하려고 했는데 여름휴가다 어쩌구 하다보니 이제 겨우 두뻔째 발표모임을 가지게 되었습니다. 지난 번에는 WebDriver에 대해서 발표를 진행했었습니다. 저는 말로하는 건 잘 못하긴 하지만 사람이 많지 않아서 연습도 하고 공부도 할겸 최대한 참여하려고 하고 있습니다.(관중이 2자리수만 되면 덜덜덜 현상이...)

발표라는 건 사실 평소에 만지고 있던 것을 하는 것이 가장 좋다고 저도 생각하고 있기는 하지만 FRENDS에 함께 하고 있는 분들의 수준도 높고 하다보니 항상 주제에 대해서 많은 고민을 하게 됩니다. 너무 뻔하고 쉽지 않으면서도 나도 공부되고 다른 사람들에게도 도움이 될수 있는 주제는 쉽게 잘 안찾아졌습니다. 블로그를 통해서도 나타나지만 엄청나게 산만한 관심사를 가지고 있기 때문에 깊이는 좀 부족해서 무언가 발표하려고 하면 좀 어려움이 있습니다. 이런 저런 고민을 한참 하다가 언젠가 한번은 만져보려고 하고 있던 Socket.IO를 주제로 정하고 지난 일주일 내내 Socket.IO만 만지고 있었습니다.(원래는 3~4일 정도에 완료예정있습니다만 ㅡㅡ;;)





Socket.IO에 대해서
Scoket.IO"The cross-browser WebSocket for realtime apps"라고 타이틀이 붙어 있습니다. 리얼타임에서는 Ajax를 이용한 Polling정도가 최선인줄 알았다가 최근 몇년 사이에 급 부상한 Comet관련 기술과 HTML5와 함께 떠로은 Web Socket등의 리얼타임 기술들이 나왔습니다만 예제소스들도 많이 나오고 시연되고 있지만 실제 서비스에서는 아직 쉽지 않은 분위기라고 생각합니다. 이 부분에 대해서는 리얼타임을 커서할 능력의 서버쪽 문제나 Comet지원서버등의 문제등도 있지만 각 웹브라우저의 지원가능 범위가 다른 문제도 있었습니다.

Socket.IO는 이 문제를 해결하기 위한 라이브러리입니다. 과거 Prototype.js나 jQuery가 브라우저마다 다른 Ajax를 추상화하여 동일한 방법으로 모든 브라우저에서 Ajax를 사용할 수 있는 편의성을 제공한 것과 마찬가지로 리얼타임 기술에 대해서 추상화를 제공하고 있습니다. 또한 부하가 심한 리얼타임 애플리케이션에 상당히 적합한 node.js로 서버를 구현하였고 리얼타임 기술은 각 리얼타임 기술에 따라 서버의 처리방식도 달라져야 하기 때문에 서버쪽도 추상화하여 간단히 처리할 수 있도록 하였습니다.

Socket.IO는 LearnBoost라는 회사에서 만들었으며 Github에서 오픈소스로 개발되고 있습니다. Socket.IO를 사용하기 위해서는 서버와 클라이언트가 모두 필요하기 때문에 JavaScript파일을 위한  Socket.IO와 서버쪽 구현을 위한 Socket.IO-node  두가지 저장소에서 관리되고 있습니다.

Socket.IO 공식 홈페이지에도 언급된 것처럼 아래의 리얼타임 기술들을 모두 지원하고 있습니다.

  • WebSocket
  • WebSocket over Flash (+ XML security policy support)
  • XHR Polling
  • XHR Multipart Streaming
  • Forever Iframe
  • JSONP Polling (for cross domain)

그리고 아래의 브라우저에서 지원가능합니다.

  • Internet Explorer 5.5 - 8
  • Safari 3 - 5
  • Google Chrome 4 - 6
  • Firefox 3-4
  • Opera 10.61
  • iPhone Safari
  • iPad Safari
  • Android WebKit
  • WebOs WebKit

간단히 테스트와 예제정도를 작성해 보았기 때문에 세세한 브라우저별 이슈에 대해서는 알지 못하지만 위 언급된 내용만으로 보면 거의 모든 브라우저에서 사용가능하다고 할 수 있겠습니다.





Socket.IO 설치하기
Socket.IO는 node.js에 기반한 라이브러리이기 때문에 node.js를 설치해야 합니다. node.js의 설치에 대해서는 이전에 올린 포스팅을 참고하시면 되고 문서에 따르면 최소 0.1.1.03버전 이상을 설치하라고 되어 있습니다.(현재는 0.2.4까지 릴리즈 되었습니다.)

npm을 사용한다면 npm install socket.io 명령어로 간단하게 설치할 수 있고 require("socket.io")처럼 사용할 때 경로를 적어주지 않아도 되지만 앞에 올렸던 내용처럼 현재 약간의 버그가 있는 상태입니다.  npm을 사용하지 않으려면 Socket.IO-node 저장소에서 아래의 명령어로 내려받아서 사용할 수 있습니다.

git clone git://github.com/LearnBoost/Socket.IO-node.git socket.io-node --recursive

Socket.IO-node는 클라이언트쪽 소스인 Socket.IO 저장소와도 연결이 되어 있기 때문에 --recursive 옵션을 붙혀주어야 관련된 소스까지 모두 내려받아 정상적으로 사용할 수 있습니다.





Socket.IO 서버 사용하기

var http = require("http"),
      io = require("./path/to/socket.io"),
      server = http.createServer(function(req, res) {});

server.listen(8080, null); // HTTP 서버 생성
                    
var socket = io.listen(server); // Socket.IO를 HTTP서버에 연결

socket.on("connection", function(client) { // 클라이언트가 연결되었을 때의 리스너
    client.on("message", function(msg) { }); // 클라이언트가 메시지를 보냈을 때의 리스터
    client.on("disconnect", function() { }); // 클라이언트가 연결을 끊었을 때의 리스너
});

HTTP서버에 Socket.IO를 연결하고 리스너를 등록하는 것 만으로 아주 간단하게 리얼타임을 위한 서버를 구성할 수 있습니다. 이렇게 구성할 경우 별다른 설정없이 http://호스트네임/socket.io/socket.io.js 에서 Javascript파일을 제공하게 됩니다.

클라이언트에게 메시지를 보내는 함수는 2가지가 있는데 client.send();와 client.broadcast(); 입니다.(여기서 client는 "connection" 리스너에서 파라미너로 받은 client입니다.) send() 메서드는 현재 접속한 사용자에게만 메시지를 보내는 것이고 broadcast()는 사용자외 다른 모든 사용자에게 메시지를 보내는 것입니다.





Socket.IO 클라이언트 사용하기
위에서 말한 것처럼 Socket.IO 서버에서 JavaScript파일을 제공하고 있지만 CDN을 통해서도 제공하기 때문에 아래 2가지 방법을 통해서 socket.io.js를 사용할 수 있습니다.

<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script src="socket.io/socket.io.js"></script>


var socket = new io.Socket("localhost"); 

socket.connect(); // 서버에 연결

socket.on('connect', function(){ }); // 연결되면 발생하는 리스터
socket.on('message', function(msg){ }); // 서버로부터 메시지를 받으면 발생하는 리스너
socket.on('disconnect', function(){ }); // 연결이 종료되면 발생하는 이벤트 리스터

socket.send('Hello world!'); // 서버로 메시지 전송
socket.disconnect(); // 연결 종료

클라이언트 소스도 서버에서 사용했던 것과 거의 유사한 방식으로 사용이 가능합니다. 브라우저에 상관없이 위의 코드만으로도 실시간으로 서버와 메세지를 주고 받는 것이 가능해 집니다. 열심히 파보긴 했는데 사용법은 너무 간단해서 설명이 그다지 필요없을 정도네요.
2010/10/27 02:58 2010/10/27 02:58