tanaka's Programming Memo

プログラミングについてのメモ。

パーフェクトJavaScript勉強メモ(17)

前へ | 次へ

17章 WebSocket

WebSocket概要

WebSocketとは
  • p393 1本のHTTP接続上で双方向のメッセージやりとりができる
  • HXMLHttpRequestとServer-SentEventsを利用したやりとりよりも効率がよく、設計や実装もシンプル
  • 補足:2015/2/12現在、Operamini以外の主要やブラウザに実装
既存の通信技術
  • XMLHttpRequest(XHR)
    • クライアントからサーバ方向への非同期通信手段の一つ
    • クロスオリジン通信ができない。これを解決するのがLevel2
    • p394 1バイトの送信でも、リクエストヘッダが付与されるので数Kバイトの通信になる
  • Server-Sent Events
    • サーバからのプッシュ通信のための仕様
    • 仕様に従ったフォーマットでサーバサイドから通常のHTTPレスポンスを返すことでプッシュ通知が可能
    • 補足:2015/2/12時点で、IEが未対応
  • AJAXポーリング
    • プッシュの代替として、定期的にサーバに送信要求の有無を問い合わせる
    • p395 送信要求がないときにも通信が発生すること、サーバに更新があってもクライアントからの問い合わせがないと返信できないので遅延が発生することがデメリット
  • Comet(ロングポーリング)
    • Cometとは、サーバ側から必要なタイミングでレスポンスを返せるような実装方法
    • 通常は、クライアントからのリクエストに対して、すぐにレスポンスしてコネクションを切断する
    • ロングポーリングでは、クライアントからのリクエストにすぐには返信しないことで、必要なタイミングで返信する
    • 返信が完了したら、クライアントはすぐに次のリクエストを発行して、継続的にコネクションを維持する
    • サーバサイドの同時接続数の調整やキープアライブを大きめに設定する
  • Comet(ストリーミング)
    • p396 ロングポーリングの改善策
    • クライアントからのコネクションに対して、常に結果を返し続けることで接続を維持する
    • サーバからのレスポンスに適切に対応
    • この仕様を策定したのがServer-Sent Events
    • Server-Sent Eventsが使えなくても、iframeを使って実現できる。実現例。注意点もある
WebSocketの仕様
  • p397 JavaScriptAPIとサーバとの通信に関するプロトコル仕様に分かれている
  • 仕様はIETFで策定中
WebSocketの動作
  • クライアント側からHTTPで送信し、サーバが接続許可のレスポンスを送ると、ブラウザはコネクションをWebSocketにアップグレードする(ハンドシェイク)
  • p398 ハンドシェイクはGETで行い、プロトコル(ws://またはwss://)、サブプロトコルドメイン、ポートなどを指定
  • HTTPヘッダが付加されるのはハンドシェイク時のみなので、UserAgentなどのチェックはここで行う

基本操作

コネクションの確立
  • クライアント側でWebSocketクラスのコンストラクタ呼び出し。ポートは省略すると80,443番がデフォルト
  • 同一オリジンには制約されない。必要に応じて、サーバ側で接続制限をする
  • 第2引数のサブプロトコル名は省略可能。サーバはやりとりするプロトコルを返す。このプロトコルはアプリレベルのプロトコルで、必要によって方式を変えたい時に利用
  • ハンドシェイクが成功するとopenイベントが発火
メッセージの送受信
  • p399 サーバにデータを送るのはsend、受信はmessageイベントを捕捉
  • サーバからのデータはmessageイベントオブジェクトのdataプロパティに格納
  • JSONを利用をすればJavaScriptオブジェクトの送受信が簡単にできる
コネクションの切断
  • クライアント側から明示的に切断するのはcloseメソッドを呼ぶ
  • 切断されるとcloseイベントが発火
  • p400 スリープしてからや長時間経過して接続が切れることがあるので、自動的に再接続をする仕組みを実装しておくとよい
コネクションの状態確認
バイナリデータの送受信
  • p401 WebSocketで送受信可能なフォーマットは文字列、Blob、ArrayBufferの3つ
  • 書籍の時点では、Blob、ArrayBufferはブラウザで未実装
  • バイナリデータを送受信する場合も、文字列と同様に、BlobやArrayBufferをそのまま指定するだけでよい
  • 受信する場合は、binaryTypeにblobかarraybufferを指定する。指定しないとblob
WebSocketインスタンスのプロパティ一覧

WebSocket実践

  • p402 Node.jsを利用したチャットアプリの例
Node.jsのインストール
  • WebSocketとのサーバ側のやりとりのためのライブラリは様々な言語で公開されている
  • Node.jsのバージョン管理ツールnaveを利用したインストール方法の紹介
  • p403 Node.js用のパッケージマネージャであるnpmをインストール
  • websket-serverをインストール
  • Windowsの場合はCygwinVirtualBox上のUbuntu、あるいはNode.jsのWindows用のもの
サーバサイドの実装
  • 返信先の3パターン
    • メッセージ送信元にデータを返信
    • メッセージをすべての人にブロードキャスト
    • メッセージを条件に該当する人にだけブロードキャスト
  • p404 WebSocketサーバの実装例
p404 クライアントサイドの実装
p405 クライアントサイドの実装2
  • p407 JSONで必要なデータをプロパティに設定してやりとりすることで、サーバサイドはそのままで、クライアントサイドだけで色々なことが可能になる

前へ | 次へ