Socket.IO가 왜 크로스-브라우저를 지원하는지, 어떻게 구동되는지 이해하기 위해 소스를 살짝 들여다 보았습니다. Socket.IO에서 제공되는 이벤트 핸들러 외 nativeJSON 애뮬레이션 그리고 코드의 대부분이 통신 방식에 관련된 코드들로 구성되어있습니다. 한마디로 말하자면 브라우저에서 사용가능한 모든 통신 수단과 방법을 동원하여 구현했다고 할 수 있겠습니다.

io.connect 함수에 의해 최초 한번의 jsonp 통신으로 handshake가 발생하며 이때 서버로부터 sessionid, timeout 설정 값, 사용 가능한 통신 방식들(transports)을 수신합니다. 통신(Transport)부 구분은 HTML5의 WebSocket 지원 여부 판단을 시작으로 플래시를 이용한 웹소켓인 'Flashsocket'의 사용 가능 여부 및 WebSocket API 애뮬레이션(플래시소켓은 플래시 플래이어 10.0.0 이상을 필요로 합니다.), 그 다음으로 iframe을 이용한 통신 구현인 'HTMLFile', 그리고 크로스-도메인(XDomain)을 지원하는 XHR 지원여부를 구분한 'XHRPolling', 끝으로 JSONP를 이용한 'JSONPPolling' 방식이 있습니다. 이 통신들은 기본적으로 크로스-도메인인지에 대한 여부에 따라 작동이 조금씩 달라집니다.

WebSocket은 물론 Comet이 사용하던 Bayeux기반의 폴링(Polling) 방식을 포함한 Flashsocket 등의 다양한 통신방식 지원으로 인하여 크로스-브라우저를 지원할 수 있던것이었네요. 네이티브 웹소켓과 폴링 방식의 통신을 결합할 발상을 한 자체가 정말 대단합니다. 더욱 놀라운 사실은 이렇게 복잡한 통신 로직을 사용자가 조금도 신경쓸 필요없이 만들었다는 것입니다. 다음 예제를 보시죠.

서버:

var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});

클라이언트:

  var socket = io.connect('http://localhost');
  socket.on('news', function (data) {
    console.log(data);
    socket.emit('my other event', { my: 'data' });
  });

Socket.IO는 양 사이드 모두 'on' 이라는 메서드를 통해 이벤트를 모니터링(subscribe)하며, 'emit'이란 메서드를 통해 데이터를 전송(send)합니다. 정말로 Input/Output 밖에 없습니다. 각 이벤트들은 사용자에 의해 마구마구 생성될수 있으며, 서버-사이드에서 발생하는 connection는 최초 io.connect에 의해 handshake가 성공적으로 이루어졌을때 진입합니다. 또한 handshake에서 돌려줄 사용 가능한 통신 방식은 기본으로 ['websocket', 'htmlfile', 'xhr-polling', 'jsonp-polling']이며 먼저 정의된 순으로 사용 우선순위를 가집니다. 그리고, JSON 포맷의 패킷전송을 위해 parse/stringify 구차하게 해 주는것 따위는 자동화 되어 있으므로 신경쓰지 않아도 됩니다. 이건 뭐 DOM 이벤트 다루는 것 보다 더 쉽네요. 자, 이제 장난감은 준비되었습니다.

Comments

Got something to add? You can just leave a comment.

Your Reaction Time!

avatar

captcha