socket.io.jsを使う
websocket使ってみたくてsocket.io.js試してみました。
ググって出てくるWeb上の日本語記事はバージョンが古いのかうまく動かなかったので本家のGet Startedでやってみた。socket.ioの入門はとりあえずchatを作るのが王道っぽいです。
試したバージョンは以下のとおりです。
- socket.io 1.2.1
- express 4.10.2
- node 0.10.28
ソースは以下に置いておきました。実質サンプルのまんまですが。。。
https://github.com/minamijoyo/chat-example
以下、適当な解説。
サーバ側の実装
var app = require('express')(); var http = require('http').Server(app); var io = require('socket.io')(http);
初期化処理はexpressのアプリ作って、それでhttpのサーバ作って、それでsocket.ioのオブジェクト作る。
app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); });
expressのルーティングで/に来たらindex.html返すようにしておく。
io.on('connection', function(socket){ socket.on('chat message', function(msg){ io.emit('chat message', msg); }); });
io.onでsocket.ioのconnectionイベント登録して、そのコールバックでその他ユーザ定義のイベント(ここではchat messageイベント)を登録する。
io.emitでイベント生成できる。ここではクライアントからもらったメッセージを投げ返してるだけに見えるけど、ブラウザのタブ2枚開いて試してみたら分かるけどタブ1で投げたメッセージがサーバに届いて、サーバからio.emitするとタブ1とタブ2両方にメッセージが届いてるのでブロードキャスト動作になってる。
試しに
io.emit('chat message', msg);
を、以下のように書き換えると、メッセージ送信したクライアント以外のその他のクライアントにブロードキャストすることもできる。
socket.broadcast.emit('chat message', msg);
最後にポートをリッスンする。
http.listen(3000, function(){ console.log('listening on *:3000'); });
クライアント側の実装
<script src="https://cdn.socket.io/socket.io-1.2.1.js"></script>
socket.io.jsのライブラリを読み込ませる。ちなみに
<script src="/socket.io/socket.io.js"></script>
と書いて、サーバ側に明示的に/socket.io配下にsocket.io.jsを"配置しなくても"なぜだかよしなにsocket.io.jsのファイルをサーバが返してくる。自分でルーティングも書いてないし仕組みはちょっとよくわからんので気持ち悪いけど、たぶんサーバ側のsocket.ioのライブラリがよしなにハンドリングしてくれてるのだと思う。
サンプルではjqueryも読み込んでるけど、単にデモ画面の描画用で特にsocket.ioと依存関係があるというわけではない。
var socket = io();
クライアントの初期化処理。明示的に宛先を指定していないけどデフォルトはこのHTMLページを返しているサーバに繋ぎに行ってくれるそう。
$('form').submit(function(){ socket.emit('chat message', $('#m').val()); $('#m').val(''); return false; });
フォームから文字列拾ってsocket.emitで投げる。
socket.on('chat message', function(msg){ $('#messages').append($('<li>').text(msg)); });
受信はsocket.onでイベントハンドラ仕掛けて、あとはよしなに画面を更新する。
使ってみて雑感。
割とシンプルなかんじでクライアントとサーバ間でメッセージが投げあえるのでリアルタイムでなんかやりたいときにはよさそうなかんじ。特にサーバからpushでデータ配信できるのでそーゆー配信系のアプリとかによさそう。
あと過去バージョンからAPIが変わってるのか(?)昔のブログ記事とかのソースだと動かなかったりするのでそのへん注意。