WebSocketに入門するための知識
はじめに
個人的に、WebSocketを触る前に知っておきたいなと思う知識をまとめました。
入門的な知識にとどめて、深い部分までは触れていません。(別記事でもっと深く触れる予定です。)
対象読者
WebSocketとは?と検索している人
駆け出しWebエンジニア
WebSocketとは
サーバーとクライアント間の永続的な TCP接続を可能にするプロトコル。
HTTP通信ではクライアント起点で情報のやり取りを行うが、WebSocketでは、クライアントとサーバーの双方向に情報のやり取りが一つのコネクションで行える。
ヘッダーが小さく、通信のオーバーヘッドが少なくなるように設計されている。
WebSocketの歴史
webブラウザでは、JavaScriptの発展に伴い非同期通信が盛んに行われるようになった。
そこで、クライアント側からの通信だけでなく、サーバー側からの通信の需要が高まり、WebSocketの技術が開発されていった。
WebSocket以外だと、ロングポーリングの技術を使ったCometなどがある。
ロングポーリング
クライアントからのリクエストに対して即座にレスポンスを返す通常の方法とは異なり、
タイムアウト直前までコネクションを保持し続けて、その間にあった変更をまとめてレスポンスする方法。
Cometとは
ロングポーリングを使用して、その間に発生した変更をまとめて返す方法。
Cometには下記のような問題があり、広くは普及しなかった。
- スケーラビリティ
コネクションを長期間保持しておくため、スレッドやメモリのリソース消費が多い。
多数のクライアントと接続することで、より逼迫していく。 - ネットワークの遅延
タイムアウトギリギリまでレスポンスを引き延ばすため、レスポンスにリアルタイム性を持たせることが難しい。
WebSocket導入前に...
WebSocketはとても便利な技術だが、こちらの記事にもあるように、導入するとセキュリティ、テスト、実装が複雑になるケースが多い。
設計をする時にも、どのタイミングで、誰に、何の情報を送信するのか?既存イベントと統合させるか?イベントのペイロードを効率よく作るには?と悩むポイントが増えることがよくある。
無駄なイベントの送信がパフォーマンスに影響する場面も多々あるように感じるので、そもそもリアルタイム性が必要なのかを考えた上で導入したい。
wsとwss
httpとhttpsと同じように暗号化が挟まるかどうかの違い。
wsは、リクエスト => TCP => WebSocketの間の通信経路で、HTTPプロトコルと異なるプロトコルでデータが流れるので、プロトコルの差異により通信が失敗するケースが割とあるらしい。
一方wssは、リクエスト => TCP => SSL/TSL => WebSocketの流れなので、通信経路の段階では暗号化されているため引っかかりにくい。
関連技術
Socket.io
WebSocketをベースにしたリアルタイム通信のためのライブラリ。
サーバーがWebSocketに対応していなくても、ロングポーリングを自動でやってくれる。
ただし、接続の流れがロングポーリング => 可能だったらwsにアップグレードという流れなので、初期接続に時間がかかる。
room機能があるので、決まったクライアントのグループにイベントを一斉送信したいときにも有用。
Redis
インメモリのキーバリューストア。
下記の働きで、クライアントサーバーだけでなく、クライアント同士でのメッセージの送受信を実現できる。
-
セッション管理
クライアントとサーバーの接続情報を保持しておける。
これによって、複数のWebSocketサーバーとデータを同期することが可能。 -
メッセージブローカー
Pub/Sub機能を利用してメッセージを送受信できる。
ユーザーAのアクションを別WSサーバと接続するユーザーB, Cに同期させたい場合、
下記の図で言うと、Pub/Sub機能を使って、ユーザーA => WSサーバーA => Redis => WSサーバーA,B,C => ユーザーA,B,C のように情報が流れる。
Redisサーバー
┏━━━━━━━━━━╋━━━━━━━━━━┓
WSサーバーA WSサーバーB WSサーバーC
┃ ┃ ┣━━━━━━━━━┓━━━━━━━━━┓
ユーザーA ユーザーB ユーザーC ユーザーD ユーザーE
最後に
WebSocketとは?から、関連知識までをまとめた。
Webエンジニアで生きている以上は、熟知していたい技術だなと思うので、この入門的な知識をより深めていきたい。
参考記事に記載したWebSocketサーバー作ってみた系の記事で、より理解が深まると思うので初学者にはぜひお勧めしたい。
Discussion