by shigemk2

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

はじめてのWebSocket

Eiji Kitamura
@agektmr

はじめに
HTML5
スマホ、SNS、ノーティフィケーション(push)の発達でリアルタイム性の重要度が
増してきている

FB、Twitterなどの通知(notification)により
スピードが上がってきている。

リアルタイムウェブのユースケース

SNS
ストリーミング
ゲーム
チャット

解決策(websocket以前)
ajax/polling(定期的に問い合わせを行い、非同期通信を行う)
comet/long polling(サーバ側に問い合わせを行い、更新があったときのみ通知する)


websocket
ブラウザとサーバの間でコネクションが生まれ、
リアルタイムにpushする。
(今までは問い合わせをしないとサーバは何もしてくれなかった)

全二重の双方向通信を可能にする技術がwebsocket
不要なHTTPを削除しまくる

仕様
WebSocket API
WebSocket Protocol

1. ブラウザ対応
Chromeはモバイル版を含め最新版にも対応している(フルサポート)。
IEのモバイル版はサポートしていない。

2. 未対応ブラウザについて
Polyfill(JSライブラリ)で対応可能
web-socket.js
Socket.IO
IEの古いやつでも一応動くはず。

3. サーバ実装ライブラリ対応状況
フロントエンドだけでなくサーバ用のライブラリもある。(node.js ruby java
など)

4. PaaS対応状況
AWS(ELBに難あり)
Nodejitsu
NodeNinja

5. 実際に利用しているサービス

  • アメーバピグライフ
  • 緊急地震速報 (ChromeExtension)
  • マインドフリー Handy Studium


サーバに接続する
(第二引数は省略可)

var connetion = new WebSocket("ws://echo.websocket.org", ['soap','xmpp']);

一回newしたらあとはイベントを拾うだけ。
イベントは4つくらいしかない。

Echoサーバーで試す
ws://echo.websocket.org/

node.js & ws

  • node.js
    • サーバサイドJavaScriptの実行環境
    • ノンブロッキング
    • 非同期IO
  • wsとは
    • node.jsのwebsocketライブラリ
// wsライブラリを読み込む
var WebSocket = require('ws').Server;

シンプルなメッセージを送るだけならコードはとても単純

var msg = "Hello, world!";
connection.send(msg);

誰が送ったか分かるようにするにはメッセージの種類を分ける
msgにdataやtypeを追加する

やりたいことが増えれば増えるほどオブジェクトが複雑になる

これを解決しうるのがSubprotocolだが、
SubprotocolはSOAPのみ...
そのため、独自にプロトコルを構築したSocket.IOを利用する

メッセージだけでなくバイナリデータを送ることも出来る
つまりリアルタイムで音を流したりできる

ブラウザ上のバイナリ
Blob
ArrayBuffer
がある
送信時はそのまま放り込む
受信時は形式(Blob or ArrayBuffer)を予め決める

msgを構造化しないと誰に何を送りたいか指定できない
ただし、バイナリも構造化する必要がある。

web-socket.js(どの環境でも試せる)
Socket.IO(プロトコルをあまり気にしないでまとまったことができる)
Autobahn(ブラウザの対応状況をチェックする)
HTML5Rocks

SPDYとの互換性は目下模索中
iphoneとかでも使えます(バージョンには気をつけよう)