발표라는 건 사실 평소에 만지고 있던 것을 하는 것이 가장 좋다고 저도 생각하고 있기는 하지만 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>
<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(); // 연결 종료
클라이언트 소스도 서버에서 사용했던 것과 거의 유사한 방식으로 사용이 가능합니다. 브라우저에 상관없이 위의 코드만으로도 실시간으로 서버와 메세지를 주고 받는 것이 가능해 집니다. 열심히 파보긴 했는데 사용법은 너무 간단해서 설명이 그다지 필요없을 정도네요.
우선 책내신 거 축하드립니다.
제가 Socket.IO를 써서 채팅 예제를 만들었는데 IE에서만 유독 일정시간동안 채팅이 이루어지지 않으면 Connection이 끊어지는 현상이 있더라구요. IE에서는 HTMLFile인가를 써서 Connection을 하는데 고유 버그인지 제 잘못인지 모르겠습니다. 혹시 이에 대해 아시는게 있으신가요?
축하해 주셔서 감사합니다.
제가 IE를 잘 쓰지 않아서 해당 부분은 경험해 보지 못했네요. 검색해봐도 잘 안나오는것 같은데 reconnect 옵션이 있어도 그런 문제가 생기나요? 시간나는대로 한번 테스트 해보겠습니다.
우연히 검색중에 발견하여 글 남깁니다.
htmlfile은 여러가지 버그가 있는것이 여러가지 test를 통해 밝혀졌습니다.
다음과 같이 설정하시고 쓰시기 바래요.
io.set('transports', ['websocket', 'flashsocket',/*BUG!!! 'htmlfile',*/ 'xhr-polling', 'jsonp-polling']);
구버젼 IE에서는 flashsocket이 직빵입니다. :)
같은 문제로 고생하시는 분들께 도움이 되기를...
안녕하세요 outsider님 책사서 nodejs 경험중인 대학생입니다^^
질문이 있어서 코멘트 답니다 ㅎㅎ
websocket으로 실시간 웹구현을 할때 tcp 서버를 이용할 것이라고 생각했는데 http서버를 쓰는이유는 무엇인가요?ㅎㅎ
그리고 socket.io가 handshake나 protocol 처리를 다 해주는 건가요?
websocket potocol 을 어떻게 처리하는지에대한 참고 사이트가 있는지도 궁금합니다 ㅎㅎ
안녕하세요.
http 자체가 tcp위에 구현된 것이긴 하지만 웹소켓자체가 웹을 위한 스펙이기 때문에 기본적으로 HTTP를 쓰도록 되어 있습니다(웹의 스펙이니까 http를 안쓸 이유가 더 없다고 봐야죠.)그리고 웹소켓의 핸드쉐이크과정조차 기존 웹 환경에 친화적일 수 있도록 HTTP로 업그래이드 요청을 보내면 그걸 이용해서 ws 프로토콜로 변환해서 핸드쉐이크를 맺도록 되어 있습니다.
http://www.slideshare.net/trustinlee/websocket
ws 프로토콜자체를 물으신건지 socket.io의 처리방식을 물으신건지 모르지만 전자라면 이희승님의 위 발표자료를 보시면 도움이 되실겁니다.
그리고 socket.io가 내부에서 핸드쉐이크나 프로토콜처리까지 다 해줍니다.
감사합니다
하이브리드 앱 공부하다가 node.js까지 넘어 오게되었는데
서버프로그래밍 입문을 websocket과 nodejs로 하려다보니 모르겠네요
많은 도움 되었습니다 감사합니다