by shigemk2

当面は技術的なことしか書かない

大阪Node学園一時限目 Socket.IOとリアルタイムなナニか

Socket.IO http://socket.io/
日本語訳: http://jxck.github.com/socket.io/

Socket.IOとは?

クロスブラウザ / クロスデバイス上でリアルタイムアプリケーションを可能
にする

リアルタイムアプリケーションって?
Socket.IOを使って(Ajaxではない)を利用して、
リアルタイムでの通信を行う

Socket.IOはリアルタイムなものなのか?
ググる
http://www.atmarkit.co.jp/fcoding/articles/websocket/01/websocket01a.html

が出てくる

websocketとは?

RFC 6455から
双方向通信を行う
HTTPやAjaxは、リクエストが来たら、その都度レスポンスを「待つ」
待つのがしんどいですね。

websocketコネクション上でやりとりする。(コネクションを貼りっぱなし)
都度コネクションを貼る必要がなくなるので、通信ロスが減る

websocket沿線
html5に含まれるapi規約だったが、現在は独立した規約になっている

2010.5 Draft Standard
2011.12に、ようやく使用が確定する

websocketが使えるブラウザ、デバイス
ChromeFirefoxOperaでも使える(Safariでも使えるか?)
IEはスルー
https://developer.mozilla.org/en/WebSockets
とどのつまり、全てのブラウザでは使えない

WebSocket非実装ブラウザへの対応
WebSocketに対応しないブラウザ(主にIE)へはどのように対応しているか?

Socket.IOのクロスブラウザ/デバイス対応

Supported transports
http://socket.io/#browser-support

WebSocket
Adobe® Flash® Socket
AJAX long polling
AJAX multipart streaming
Forever Iframe
JSONP Polling

Socket.IOを使うと、IEでもwebsocketが使える

Comet (AJAX long polling)
Cometはそれほど新しい技術ではない(2006から)
DocsやWaveで使える

websocketを使ったハイブリッドな技術

Socket.IOの利点
クライアント・サーバ側ともSocket.IOの独自APIで使える
Proposed Standardになったとはいえ、まだまだ過渡期にあるWebSocketの仕様
を深く追わなくてもよい。

どのブラウザでも、詳しい中身を知らずともwebsocketが使える
プログラムが書ける

Socket.IOブラウザ対応 (デスクトップ)

Socket.IOブラウザ対応 (モバイル)

結構古いブラウザから対応しているのね。

Socket.IOピックアップ
v0.7で大きな変更が加えられた

Socket.IO v0.7からの変更点(抜粋)

  • 名前空間
  • 揮発性メッセージ
  • 送信確認コールバック処理
  • etc...

Socket.IOで抑えておきたいポイント

  • コネクション接続時処理
  • メッセージ送信 - emit("event")
  • メッセージ受信 - on("event")

(v0.7からの変更)

  • 名前空間 - of/for('/name_space')
  • 揮発性メッセージ - socket.volatile.emit
  • 送信確認コールバック処理 emit callback

サンプル

var io = require('socket.io').listen(80);
io.sockets.on('connection', function ( socket ) { //コネクション接続時のイベント
    // コネクション接続時の処理を記述
    // 送信
    socket.emit('welcome', { hello: 'world' }); //クライアントに返す
    // 切断処理
    socket.on('disconnect', function () { // コネクション切断時のイベント
	// コネクション切断時の処理を記述('user disconnected'メッセー
	// ジで送り返す
	io.sockets.emit( 'user disconnected' );
    });
});

メッセージ送信 - emit("event_name")の使いかた

以前は「send()/broadcast()」などがあった
これらがemitにまとめられた。

// 自分自身へ送る
socket.emit("event_name", data);
// 自分以外全員へ送る
socket.broadcast.emit("event_name", data);
// すべて(自分を含む全員)に送る
io.sockets.emit("event_name", data);

メッセージ受信 - on( "event_name" )
サーバーサイド/クライアントサイドで対となる"event_name"が紐付く

//1,
socket.on( "event_name", function( data ){
//送信元の socket.emit( "event_name", data ); と紐付く
});
//2,
socket.on( "custom event", function( data ){
//送信元の socket.emit( "custom event", data ); と紐付く
});

名前空間 - of('/chat_room')

今まではチャットルームを自分で区切る必要があった。
たとえばチャットルームで区切るなど...
しかしこれからは、名前空間を使ってコネクションの共有範囲グループを分割
できる。

    <script>
        var socket = io.connect('http://localhost/');
        var hoge_chat = socket.of('/hoge');
        var fuga_chat = socket.of('/fuga');
        // コネクションごとにメッセージを分けられる
    hoge_chat.on('connection', function () {
            hoge_chat.emit('hoge_in');
        });
        fuga_chat.on('connection', function () {
            fuga_chat.emit('fuga_in');
        });
    </script>

揮発性メッセージ - socket.volatile.emit
Socket.IOメッセージ送信時、通常失敗した場合はリトライがかかる。
(座標追跡データなど)
そこで、リトライの必要のないデータは、
emitに「volatile」をつけることで揮発性メッセージとなる(一回きり)
座標追跡などタイマーを使用する場合に有効

    var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
    var tweets = setInterval(function () {
	getBieberTweet(function (tweet) {
	    socket.volatile.emit('bieber tweet', tweet);
	});
    }, 100);
    socket.on('disconnect', function () {
	clearInterval(tweets);
    });
});

送信確認コールバック
送信先へのメッセージ送信が成功した時に発火する関数を定義
(第三引数でやる)

<script>
  socket.emit('ferret', 'tobi', function (data) {
  console.log(data); // data will be 'woot'
  });
</script>

Node.jsが利用できるサービスとか

Joyent
https://no.de/
Heroku
http://www.heroku.com/
DotCloud
https://www.dotcloud.com/
Node Ninja
https://node-ninja.com/
Cloud Foundary
http://www.cloudfoundry.com/
vps??
etc

では、リアルタイムなSocket.IOを使って何ができるのか

Socket.IOはどんなフィールドで使える(使いたい)と思いますか?
ゲーム、webが多い、かな?(でもゲームが一番多いか)

Chrome開発版がWebRTCを実装 - JavaScriptからカメラやマイクが利用可能に
http://news.mynavi.jp/news/2012/01/23/041/
Javascriptでリアルタイムにカメラやマイクが使える

質疑応答
Q. 東京であった勉強会で、イベントがバレると誰でも操作できちゃう問題をどう
するか?
A. URLで認証をかけたページが存在する
別のURLで認証を掛けたページがあって、別の端末で操作している。
SyncModeとLockModeがあり、コントロールに入ったり外れたりできる。
Sync Mode Lock Mode を解除すると、自由に操作できるようになる。
ディレクトリ毎にコネクションを区切るとか。

開発はJettyを使ってもいいか。

人数制限→理論上ソケットの数に特に上限はない。サーバーの能力が上限とな
る。
チューニング次第。

websocketの他の使い道
MtoM(PCやブラウザだけでなく、スマートグリッドでの
利用も可能)
websocketを利用することで、どのくらい電力が使われているかが
分かる

ネットワーク上でwebsocketを使う人が多いかもね。
バイナリが使えるようになり、レスポンスが稼げるかもしれない。
古いほうから新しいほうへソケットを繋ぐことが出来る。
websocket.ioを、サーバーでもクライアントでも同じ文法で書ける