WebSocketに触れる機会があったのですが、そもそもWebSocketについての理解ができていなかったのでここで丁寧にみていこうと思います。

 

WebSocketとは?

Webにおいて双方向通信を低負荷で行うための仕組みです。

 

これまでのWeb通信

WebSocketのありがたみを実感するには以前までのWeb通信の仕組みを理解すると良いです。

まず以前までのWeb通信の代表格はHTTPでした。(今でも多くのWebアプリで使用されています。)

このHTTP通信は主にHTMLで電子化された文書を転送するためのプロトコルです。

 

HTTP通信の特徴

  • 1回のコネクションで1回のリクエストしか送れない
  • コネクションはクライアント側しか開けることができない
  • サーバー負荷、ネットワーク負荷、ブラウザ負荷が多い
  • ヘッダーが冗長

ボトルネックになっている主な特徴は上の通りです。

もちろんこのような弱点を克服しようとする動きもみられました。

コネクションの冗長性に対してはクライアントが一定間隔でサーバとコネクションを確立する方法(ポーリング)、一方向通信に対してはcometという疑似的なサーバプッシュ機能などが実装されてきました。

しかし、こうした技術はコーディングに無駄があり、HTTP通信の根本的問題を解決することができていませんでした。

 

Web用途の変化とHTTP通信

そもそもHTTP通信は、電子文書を送信するための通信方法として誕生したわけです。

しかし近年、Webの用途も多様化し、SNSやショッピングサイト、ゲームなどが登場するようになります。

こうしたWebアプリではよりリアルタイム性が要求されるようになります。

以前まではそうしたリッチな機能はFlashなどのプラグインで対応することが多かったのですが、HTML5の標準化が進むにつれて、プラグインは非推奨になります。

こうした流れの中でリアルタイムに通信が続く新たな通信方法が求められるようになりました。

こうした新たなニーズに対応したのが「WebSocket」になります。

 

WebSocketの特徴を丁寧に見る

こうした経緯を踏まえながらWebSocketの特徴を見ていきましょう。

まずHTTP通信と決定的に違うポイントを挙げておきます

  • 一回コネクションが確立すれば複数回リクエストを送られる
  • サーバー側からも情報の送信ができる(双方向通信)
  • 通信量の削減

 

WebSocketではセッションを張ってからコネクションが確立できれば、その後は切断するまで何度もリクエストを送ることができます。HTTP通信のように一回一回コネクションを確立する必要がないため低コストな通信が実現できます。

さらにサーバプッシュ機能も備わっていて、従来クライアント側からサーバ側という一方向でしか送信できなかった情報を双方向で通信できるようになりました。

新しい技術ということでIE10以上でないと対応していないといった懸念材料はもはや克服されており、標準APIも用意されています。

 

WebSocketの通信の仕組み

では、どのように双方向通信を実現しているのでしょうか。

WebSocketの仕組みを流れに沿って簡単に説明していきます。

 

① ハンドシェイク

ハンドシェイクとはわかりやすく言うとコネクションの確立のことです。

このハンドシェイク自体はHTTP通信で行われています。

z実際のクライアントからサーバに送られるリクエストは次のようになっています

このupgrateヘッダによって、サーバ側に「これからWebSocketを使用するよ」と伝えます。

ここでHTTP通信からWebSocketへと通信プロトコルが変更されるわけです。

ちなみにSec-WebSocket-VersionヘッダはWebSocketのバージョンを指定するもので、

Sec-WebSocket-Keyヘッダは特定のクライアントとのコネクションの確立の証明になります。

 

② 双方向通信の開始

ハンドシェイクが終わり、通信プロトコルがWebSocketに切り替わると接続が始まります。

ちなみに①で確立されたコネクションを使い続けることになります。

WebSocketでは、フレームと呼ばれる通信単位によって双方向通信が実現しています。

データ構造は割愛しますが、「小さなデータサイズで情報を送受信できる単位」と理解してくれれば問題はないでしょう。

 

③WebSocketが対応しているデータ形式

このフレームという通信単位で扱っているデータ形式は3種類です。

  • 文字列
  • Blob
  • ArrayBuffer

SNSやチャットアプリ開発でWebSocketを使用する場合などではJSONの送受信が必要になる場合が多いと思いますが、JSON自体の受け渡しはできないためエンコード、デコードする必要があります。

 

④ 接続の切断

クライアント側、サーバ側のどちらからでも切断が可能という点です。(もちろんそれに伴うエラー処理は必要になりますが)

HTTP通信でいう、close()のように簡単に接続することができます。

 

WebSocketに適した言語は?

基本的にどの言語でも扱うことができますが、その中でもNode.jsライブラリとして「socket.io」が有名です。これはNode.jsが開発された時期がちょうどチャットアプリ全盛期で、これに対応するよう設計されたという背景が理由となっているようです。

JavaScriptのAPIがかなり使い勝手が良いと評判ですが、最近ではjava用ライブラリやC++用ライブラリも充実してきています。

javaではアノテーションを使った方法も取り上げられています。

 

HTTP通信はSPDYとして進化した

一方、HTTPも進化しており、GoogleはHTTPを高度化した「SPDY」と呼ばれる通信プロトコルを開発しています。この通信プロトコルでは、一つのセッションで複数のリクエストを処理できます。

しかし、SPDYに関する資料はWebSocketに関する資料に比べてはるかに少なく、またWebSocketの使い勝手も確実に良いので、特別な理由がないかぎり、WebSocketを利用するのが無難だと思います。

 

参考記事

https://developer.mozilla.org/ja/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications