Socket.IO v0.7 のロードマップと新機能
Node と言えば、Socket.IO といっても過言ではないほど、Socket.IO は Node にとって大きい存在です。
先の NodeConf で、この Socket.IO の作者 [twitter@rauchg] より、
Socket.IO v0.7 にむけたロードマップについての発表がありました。
新機能や API の改善等、重要な変更があるようなので一部を紹介したいと思います。
資料は以下。
(注 2011/05/31 現在 v0.7 はブランチで開発中であり、以下の紹介は上記資料をもとに書いているため、実行確認はしていません。
正式にリリースされた場合は、実装をもとに別途エントリを作成すると思うので、このエントリ自体は更新されない予定です。)
API の改善
サーバインスタンス
これまでは、ソケット通信を確立するためには、 http サーバインスタンスを渡す必要が有りましたが、今後は必要なくなります。
// Before var io = require(‘socket.io’); io.listen(http.createServer()); // After var io = require(‘socket.io’); io.listen(); // creates one for us var io = require(‘socket.io’); io.listen(8000); // creates one for us and listens on port 8000
オプション設定
これまでは全体で共通する設定を listen() 時に一つ適応できましたが、
今後は、 configure() メソッドを通じて listen() とは別に設定できます。
また configure() は第一引数に環境('production','development','test' etc) を設定でき、設定を切り替える事ができます。
(おそらく express との連携を視野に入れた対応)
// Before var io = require(‘socket.io’); io.listen(app, { tranportOptions: { … } }); // After var io = require(‘socket.io’).listen(); io.configure(function () { io.set(‘polling duration’, 30); }); io.configure(‘development’, function () { io.set(‘log level’, 3); });
新機能
揮発性メッセージ
volatile.send() で、送信したら消える、揮発性のメーセージ送信をすることができます。
io.sockets.on(‘connection’, function (socket) { var t = setInterval(function () { getStock(‘APPL’, function (price) { socket.volatile.send(price); // send して終わり }); }, 500); socket.on(‘disconnect’, function () { clearInterval(t); }); };
JSON
json.send() で送信データがJSONである事を明示できます。(シリアライズ不要)
io.sockets.on(‘connection’, function (socket) { socket.json.send(‘string’); socket.json.send(5); socket.json.send([ {} , {} ]); });
メッセージディスパッチャ
複数プロセスや分散環境での容易なスケールを目的とした機能も強化されるようです。
想像ですが、デフォルトではメモリとシングルプロセスになりますが、おそらく Redis 等との連携、マルチコア環境の適応を視野に入れているのかと。
まず環境をまたいだ変数共有のようなことができるようです(?)。
io.sockets.on(‘connection’, function (socket) { socket.get(‘nickname’, function (err, nick) { // セッションに対して設定した nickname の操作。 }); });
非同期に接続中のクライアントを取得する場合は以下、環境をまたぎ、非同期に取得するようです。
io.sockets.on(‘connection’, function (socket) { io.sockets.clients(function (clients) { // 接続中のクライアントに対する操作 }); });
送達確認
単純に send() メソッドにコールバックを追加することで、送達確認処理ができるようになります。
// server side io.sockets.on(‘connection’, function (socket) { socket.send(‘bye’, function () { // 送達確認 }); }); // client side var socket = io.connect(); socket.send(‘hi’, function () { // 送達確認 });
// server side io.sockets.on(‘connection’, function (socket) { io.on(‘nickname’, function (nick, fn) { checkAvailability(nick, fn); }); }); // client side var socket = io.connect(); socket.emit(‘nickname’, prompt(‘Nickname’), function (res) { // if the function arity > 0, a callback is passed // to the event listener and the protocol signals // this is a Data ACK });
名前空間
for() を使って、イベントごとの名前空間を指定できるようになります。
(無ければデフォルト)
// namespace “” (default) io.sockets.on(‘connection’, function (socket) { io.on(‘nickname’, function (nick, fn) { }); }); // namespace “/news” io.sockets .for(‘/news’) .on(‘connection’, function (socket) { io.on(‘item’, function (nick, fn) { }); });
for() ではなく、connect() を使ってソケット自体の名前空間で分ける事ができます。
var socket = io.connect(‘http://localhost/chat’) var socket2 = io.connect(‘http://localhost/news’)
これにより、イベントやメッセージをチャネルごとに操作する事ができます。
(これまでやってきたチャネリングのハックが、実装に取り入れられる。便利!)
var news = io.sockets .for(‘/news’) .on(‘connection’, function (socket) { io.on(‘item’, function (nick, fn) { }); news.emit(‘item’); }); var stream = io.sockets .for(‘/stream’) .on(‘connection’, function (socket) { io.on(‘item’, function (nick, fn) { }); stream.emit(‘item’); });
ファーストクラスイベント
io.sockets.on(‘connection’, function (socket) { io.on('chat message', function () { }); io.on(‘nickname change’, function () { }); io.sockets.emit('user connected', socket.id); });
What’s coming
Express.IO
さらに Express との連携を強化し、Express のセッションと Socket.IO のセッションを共有する Express.IO なるモジュールが公開される予定です。
Express の作者 Tj と Socket.IO の作者 Guillermo Rauch は同じ LearnBoost で働いているため、彼らは手を組みやすい状況なのかも知れません。
目指すところは 「リアルタイム Web 界の Rails」とのこと、期待できますね!!
まとめ
Socket.IO 自体の完成度が上がる事で、リアルタイムアプリケーションを開発する際に出来ることもより増えると思います。
Guillermo Rauch さんはとてもストイックな開発者なので、今後のコミットにも期待したいと思います。
(日本に来ないかな ボソ)