ExpressとSocket.ioを使ったWebSocketのサンプルを作る

このエントリはリアルタイムWebハッカソンのハンズオン資料その3です。

前回の続きです。まずはSocket.ioを使えるようにしましょう。

app.jsの先頭を

var express = require('express');

から

var express = require('express'),
    io = require('socket.io');

にする。
また、ファイルの最後に

var socket = io.listen(app);
socket.on('connection', function(client) {
  // connect
  client.on('message', function(message) {
    // message
  });
  client.on('disconnect', function() {
    // disconnect
  });
});

を追加する。

クライアントから接続がきたらconnectに書かれた処理が、メッセージがきたらmessageに書かれた処理が、切断されたらdisconnectにかかれた処理が実行される。

次にクライアント側の処理。
sample/views/layout.jadeを開いて

!!!
html
  head
    title= title
    link(rel='stylesheet', href='/stylesheets/style.css')
    script(type='text/javascript', src='http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js')
    script(type='text/javascript', src='http://cdn.socket.io/stable/socket.io.js')
    script(type='text/javascript', src='/javascripts/client.js')
  body!= body

と記述。jQueryを使い、socket.ioのクライアントライブラリは公式サイトCDNを使い、自分で書くクライアント側のJavaScriptファイルはclient.jsという名前にする。

sample/public/javascripts/client.jsを以下の内容で作る。

var socket = new io.Socket('localhost');
socket.connect();
socket.on('message', function(message) {
  //message
});

見てのとおり2行目で接続し、サーバからメッセージがきたらmessageに書かれた処理が実行される。

んじゃとりあえず、現在接続している人数をリアルタイムに表示するプログラムでも書いてみましょう。
まずはapp.js。最後のsocket.ioのところを以下のようにする

var socket = io.listen(app);
var count = 0;
socket.on('connection', function(client) {
  count++;
  client.broadcast(count);
  client.send(count);
  client.on('message', function(message) {
    // message
  });
  client.on('disconnect', function() {
    // disconnect
    count--;
    client.broadcast(count);
  });
});
  1. countの初期値を0にしておく
  2. 接続がきたらcountを+1して、その値をbroadcast(現在のクライアント以外にメッセージを送信)とsend(現在のクライアントにメッセージを送信)
  3. 切断したらcountを-1して、その値をbroadcast

わかりやすいですね。

次にsample/views/index.jadeに以下のように追記します。

h1= title
p Welcome to #{title}
p 現在接続している人は
  span#count
  人います

そしてsample/public/javascripts/client.jsを以下のように修正します。

var socket = new io.Socket('localhost');
socket.connect();
socket.on('message', function(message) {
  $('#count').text(message);
});

以上で終了です。
それでは

$ node app.js

で起動してみましょう。
localhost:3000にアクセスすると「現在接続している人は1人います」と出るはずです。コンソールには

Express server listening on port 3000
18 Oct 18:44:52 - socket.io ready - accepting connections
xxx.xxx.xxx.xxx - - [Mon, 18 Oct 2010 09:44:56 GMT] "GET /favicon.ico HTTP/1.1" 404 - "" "Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.3 (KHTML, like Gecko) Chrome/6.0.472.63 Safari/534.3"
18 Oct 18:44:56 - Initializing client with transport "websocket"
18 Oct 18:44:56 - Client 14417221560142934 connected

こんな感じでログが出てるはずです。ちなみにfaviconがないよっていう404はウザいので適当にfavicon.icoを作ってpublic直下に置いとけばいいと思います。
では、現在のタブを開いたまま新しいタブでもlocalhost:3000にアクセスしてみましょう。「現在接続している人は2人います」と表示され、コンソールにも

18 Oct 18:50:14 - Initializing client with transport "websocket"
18 Oct 18:50:14 - Client 2343847642187029 connected

みたいに接続が増えたログが出てるはずです。
さらに、最初の「1人」と表示されていたタブを見てください。リロードしなくてもすでに「2人」になっているはずです!
タブを増やすたびに人数が増えていき、また閉じるたびに減っていくことを確認してください。
これでnode.jsを使った基本的なWebSocketの使い方は終了です。