socket.ioの習作

socket.ioの習作としてミニマムでも動きがわかるようなものをこさえてみました。ソースファイルはapp.jsとindex.htmlの二個だけ。サーバ側はexpressとsocket.ioに依存し、クライアント側でjQueryだけは用いてます。例外処理はどうしたものかまだ勉強中。おまけでサーバからプッシュするのに、タイマー使ってます。この前のprocess.nextTick()の副産物でNode.jsでタイマーがどう動くのか分かったので。
expressのバージョンは3.3.5、socket.ioは0.9.16、Node.js本体は0.10.18。コマンドラインツールが含まれるライブラリはnpmに-gスイッチでグローバルに入れ、そうでないものはローカルに入れるという教えを読んだので、expressはグローバル、socket.ioはローカルにいれたのですがWebStormではグローバルのものをデバッグ実行時に見ないという。。。なんか環境変数とおしてないからかなと思いつつ、ローカルにもexpressをいれちゃった。

//app.js
var express = require('express');
var app = express();
app.use(express.favicon());
app.use(express.static(require('path').join(__dirname, 'public')));
var server = require('http').createServer(app).listen(3000);

var chatroom = require('socket.io').listen(server).of('/chatroom');
chatroom.on('connection', function(socket) {
    heartbeat();
    socket.on('upstream', function(data) {
        chatroom.emit('downstream', data);
        heartbeat();
    });
});

var timeoutID = 0;
function heartbeat() {
    clearTimeout(timeoutID);
    timeoutID = setTimeout(function() {
        chatroom.emit('downstream', '沈黙しないで!');
        heartbeat();
    }, 10000);
}

サーバーでExpressを使わないと依存関係もさらに単純になるけど、faviconとindex.htmlとjQueryのJSファイルを配信する必要があるのでexpress.staticコネクタが便利です。その後の、中段8行のブロックがsocket.ioのチャットサーバロジック。おまけの末尾8行がサーバからクライアントへタイマー使ったプッシュのこと。

<!-- index.html -->
<!DOCTYPE html>
<html>
    <head>
        <title>Socket.io client</title>
        <meta charset="UTF-8">
        <script src='/socket.io/socket.io.js'></script>
        <script src='/javascripts/jquery-2.0.3.min.js'></script>
        <script>
            $(function() {
                var chatroom = io.connect('/chatroom');
                chatroom.on('downstream', function (data) {
                    var data$ = $('<div>').text(new Date() + ': ' + data);
                    $('#messageArea').append(data$);
                });
                $('#sendBtn').click(function() {
                    chatroom.emit('upstream', $('#textBox').val());
                    $('#textBox').val('');
                });
            });
       </script>
    </head>
    <body>
        <input type='text' id='textBox'><button id='sendBtn'>send</button>
        <p id='messageArea'></p>
    </body>
</html>

HTMLのほうは、前半がチャット受信ロジックで、後半が送信ロジック。