WebSocket とは?
Web 上でクライアント(Web ブラウザ)・サーバー間を常時接続にしておいて、双方向通信を低コストで
実現するための技術規格。プロトコル。
WebSocket の何がありがたいのか?
近年 SNS アプリなどではインタラクティブで リアルタイム
なやりとりが求められるようになってきました。
例えば、チャットアプリでは、複数のユーザーが同じページを見ているような状況で、ページを更新しなくても誰かの発言が他のユーザーのページにもリアルタイムに更新されるようにしたい、ということがあると思います。
この リアルタイムに更新
という機能を実現するためには、誰かが発言したということを サーバーからクライアントに伝える必要があります。
このような機能を WebSocket は実現します。
この クライアントからのリクエストがなくても、常時接続しているのでサーバーからクライアントに好きなタイミングで通信ができる
ということを実現できるところが WebSocket のすごいところです。
HTTP ではダメなの?
Web サイトを閲覧するするときは普通、HTTP を使うかと思います。
この HTTP は、クライアント(ブラウザ)がサーバーにリクエストを送って、一時的にコネクションを張り、サーバーがレスポンスを返す
という流れになります。そして一つのコネクションにつき、一つのリクエストしか送れません...。
つまり、基本的に HTTP は クライアントが何らかのリクエストを送らない限り、サーバーはレスポンスを返せないプロトコル
なのです。
HTTP で擬似的に双方向通信を実現することはできるが...
WebSocket はこのような HTTP(XMLHttpRequest) の欠点の補おうというニーズから生まれた規格なので、HTTP しか手段がなかった時は HTTP でなんとかしようとしていました。
具体的には、HTTP のコネクションを張りっぱなしにしておいて、クライアントから一定間隔でサーバーにポーリングし続ける。サーバーから情報を送りたいタイミングになって初めてレスポンスを返すといった具合です。
※ XMLHttpReqest の ロングポール
といい、Comet (サーバで発生したイベントをクライアントからの要請なしにクライアントに送信することができる技術) の実現に必要だった。
ただ、この方法では以下のような問題が生じました。
- ブラウザの HTTP 接続のタイムアウト(30秒など)があるため、接続し直すロジックが必要になる。
- 擬似的に双方向通信を行うため通信が発生するごとに TCP ハンドシェイクを再度行うことが必要になる。
- HTTP コネクションを長時間占有するため、その間サーバに接続する他のアプリケーションの動作に影響を及ぼす可能性がある。
対して WebSocket は...
対して WebSocket には以下のような特徴があり、HTTP の問題を解決しています。
- サーバとクライアントが一度コネクションを行った後は、必要な通信を全てそのコネクション上で専用のプロトコルを用いて行い、新たなコネクションを張る必要がない。
- HTTP コネクションとは異なる軽量プロトコルを使うなどの理由で、通信ロスが減る。
- 一つのコネクションで全てのデータ送受信が行えるため同一サーバに接続する他のアプリケーションへの影響が少ない。
WebSocket の機能・特徴まとめ
以上のことから WebSocket の機能・特徴をまとめると以下のようになるかと思います。
- 双方向通信によるサーバプッシュ機能 : 一度コネクションを確立したあとは、
サーバとクライアントのどちらからも通信を行うことが可能
になる。 - データ通信量削減 : Payload 意外の情報(ヘッダ)は最小2byte, 最大でも14byteに収まる様になっていてとても小さい。
- 低コスト : HTTP のように通信のたびにコネクションを張るということはせず、
一度コネクションを確立するとそのコネクション上で通信を行う。
WebSocket の通信の流れ
1. WebSocket opening ハンドシェイク
WebSocket opening ハンドシェイクは HTTP 通信で行われます。
クライアントのリクエストには以下のように Upgrade ヘッダ
、 Connection ヘッダ
、Sec-WebSocket-Version ヘッダ
、Sec-WebSocket-Key ヘッダ
が付けられます。
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: XXXXXXXXXXXXXXXXXX==
サーバーからのレスポンスヘッダは以下のようになります。
HTTP/1.1 101 OK
Upgrade: websocket
Connection: upgrade
Sec-WebSocket-Accept: ZZZZZZZZZZZZZZZZZZZ==
ステータスコード 101 は「Switching Protocols」で、これでコネクションが確立したことになります。
2. 双方向通信
コネクション確立後は、HTTP ではなく WebSocket プロトコルで通信を行います。
「フレーム」という単位でデータのやりとりが行われます。
実際に使ってみる
実際に WebSocket を使ってみます。
サーバーサイドのコードは以下のような感じです。Node.js を使っています。
// index.jsconstserver=require('ws').Server;constwsServer=newserver({port:8001});wsServer.on('connection',function(ws){wsServer.on('message',function(message){console.log(message);});wsServer.on('close',function(){console.log('bye.');});});
書き終わったら、node index.js
で起動させておきます。
Chrome の Developer tool でもなんでも良いのですが、クライアントのコードは以下のような感じで実行してみます。
constcon=newWebSocket('localhost:8081');con.send('Hello WebSocket!');con.close();
サーバーで以下のようなログが流れるはずです。
簡単ですね。
Hello WebSocket!
bye.
おまけ
セキュア通信は wss で
HTTP と同じく、WebSocket にもセキュア通信用のプロトコルが用意されており wss
になっています。
よく利用する Event 処理とメソッド
// Event 処理-onopen// 接続された時-onerror// エラーが発生した時-onmessage// メッセージを受け取った時-onclose// 切断された時// メソッド-send()// データを送信する-close()// 通信を切断する