Posted at

WebSocketとは?

More than 1 year has passed since last update.


はじめに

Http通信での実現が難しい双方向通信を可能とする通信プロトコル「WebSocket」について調べてみたのでまとめました。


WebSocketって?

Wikipediaによると


WebSocket(ウェブソケット)は、コンピュータネットワーク用の通信規格の1つである。ウェブアプリケーションにおいて、双方向通信を実現するための技術規格である。


とある。要するに双方向通信が可能な通信プロトコル、ということらしい。


双方向通信

では双方向通信とは何か?

ブラウザからアクセスする一般的なWebアプリでは、クライアントからサーバにリクエストを送り、サーバがクライアントに結果をリターンする、というのが主な流れだと思います。

これを逆にして、クライアントからのリクエスト無しにサーバからクライアントへの通信も行う事を双方向通信と言います。


どんな時に使う?

基本的にWebアプリではクライアント⇒サーバの通信だけで問題ないのですが、リアルタイム表示(チャットなど)を行いたい場合には、サーバからクライアントへの送信が必要となります。

双方向通信を用いない場合、クライアントから一定時間毎にサーバへ更新の有無を確認する通信を飛ばす等のやり方となってしまいますが、双方向通信を使えばデータに変更があったタイミングでサーバからクライアントに向けて通信を行い、画面に表示するということが可能となるのです。


Websocketの仕組み

WebSocketは以下の手順で双方向通信を実現しています。

1.Httpを使ってクライアント・サーバー間で通信を行い、コネクションを確立

2.以降は確立されたコネクション上で通信を行う

順番に説明していきます。


1.コネクション確立

はじめに、クライアントからサーバーに向けて以下のようなリクエストが送られます。



GET /resource HTTP/1.1

Host: xxxxx.com

Upgrade: websocket

Connection: upgrade

Sec-WebSocket-Version: 13

Sec-WebSocket-Key: xxxxxxxxxxxxxx

見て気付く人もいると思いますが、Httpのリクエストと同じ構造でWebSocketの通信も行われています。

注目すべきはUpgradeヘッダやConnectionヘッダの存在です。この2つのヘッダでHttpプロトコルからWebSocketプロトコルへアップグレードすることを表現しています。

また、Sec-WebSocket-VersionヘッダはWebSocketプロトコルのバージョンを表していて、サーバ側で送られてきたバージョンに対応出来なければ切断、という制御をしているらしい。

Sec-WebSocket-Keyはクライアントで生成された値で、この値を基にサーバ側でキー値を生成してクライアントに返却することで、クライアント側は自分のリクエストに対するレスポンスであることを確認することができる。

このリクエストに対してサーバからは以下のようなレスポンスが返却される。



HTTP/1.1 101 OK

Upgrade: websocket

Connection: upgrade

Sec-WebSocket-Accept: yyyyyyyyyyyyyyyy

リクエストと同じくHttp形式でのレスポンスとなっています。

Upgradeヘッダ、Connectionヘッダもリクエストと同様に設定されていて、最後のSec-WebSocket-Acceptヘッダが先ほど説明したサーバで生成したキー値となっている。

このやり取りをした時点でWebSocketのコネクションは確立されます。


2.双方向通信

コネクションが確立されると、以降はTCP上で双方向通信が可能となります。

その時の通信単位はフレームと呼ばれる単位で行われて、詳しい説明は割愛しますが小さい単位でデータのやり取りが可能となります。

(詳しくはこちらに記載されています)


どうやって使う?

WebSocketはコネクションを同時にいくつも接続状態にするので、Blocking I/Oを持つサーバープロセスでは1プロセスに1コネクションしか持てないのであまり相性が良くありません。

相性が良いのはNon Blocking I/Oを持ち、複数のコネクションを持てるサーバを使うのが一般的となっています。

その中でも最も有名なのはNode.jsで、WebSocketを利用するためのライブラリであるSocket.ioを使えば簡単な双方向通信アプリがすぐに作れてしまいます。


まとめ

従来の疑似的双方向通信技術を改善した通信方式で、効率よくクライアントとサーバ間の双方向通信を実現してくれるプロトコルであり、対応するサーバも増えているようです。

Node.js + Socket.ioによるアプリ作成も手軽に行えるので興味のある方は試しにチャットアプリなんかを作ってみることをおすすめします。