Websocket
Websocket
Webアプリケーションにおいて、サーバーとブラウザ(クライアント)の間でコネクションを維持し、常に双方向で通信を続けられるリアルタイム技術を指します。チャットアプリや株価のリアルタイム更新などで必須となる通信規格です。
🐾 猫で例えると?
普段からとても仲良しな茶トラとアメショは、寝る時も常に密着(コネクション確立)しています。写真のように、2匹の体同士がピッタリと接している状態で、互いに相手の体温や呼吸(ハートビート)をダイレクトに感じ取っており、どちらかが動けばすぐにもう一方も反応できる状態です。このように、一度繋がったら切断されるまでお互いに情報を送り合える状態が「Websocket」のイメージです。
🐾猫あるある:IT現場の日常
- 猫と人間がじっと見つめ合い常に意思疎通できる状態にある:一度の接続で専用の通信経路を維持し、HTTPのように都度接続を切断することなくデータをやり取りし続けるコネクション型の通信プロトコル。
- 人間の動かす猫じゃらしに遅延なく瞬時に反応して飛びつく:サーバー側からクライアント(ブラウザ)側へいつでもデータを即座に送信できる「プッシュ通知」が可能で、チャット等に適したリアルタイム・低遅延な双方向通信。
- 片方が動くともう片方もシンクロして即座に同じ動きをする:HTTP通信に比べてヘッダー情報などのデータ量が非常に小さく、高頻度なメッセージの送受信を行ってもネットワークやサーバーに大きな負荷をかけずに状態を同期できる仕組み。
💻 IT現場における「Websocket」とは?
従来のWebサイトで使われる「HTTP通信」は、ブラウザが「このページをください」とリクエストを送り、サーバーが「はいどうぞ」とレスポンスを返すと、その時点で通信がプツッと切れる「単発のやり取り(ステートレス)」が基本です。しかし、チャットアプリやオンラインゲームのように「相手からのメッセージを今すぐ受け取りたい」場合、HTTP通信ではブラウザ側から「新しいメッセージありますか?」と何度も聞きに行かなければならず、非常に効率が悪くなります。
そこで登場するのがWebsocketです。最初にHTTPで「Websocketで繋がりっぱなしにしましょう!」という挨拶(ハンドシェイク)を交わすと、通信の専用トンネルが作られます。以降は、サーバー側からも「新しいメッセージが来たよ!」と能動的にデータを押し出す(プッシュする)ことができるようになり、驚くほどリアルタイムで滑らかな体験を作ることができます。
⚠️ Websocketの仕組みと注意点
リアルタイムで便利に見えるWebsocketですが、常にトンネルを維持し続けるため、インフラストラクチャやサーバーのリソース(メモリなど)を多く消費します。おやつを出した時のアメショのように、リソースをフルに使う高負荷な状態になりやすいため、設計には注意が必要です。
JavaScriptでのWebsocket実装イメージ
フロントエンドからWebsocketサーバーに接続し、メッセージの送受信を行う基本的なコードの流れは以下のようになります。
// クライアント(ブラウザ)側のJavaScript実装例
// Websocketサーバーへのコネクションを確立
const socket = new WebSocket('wss://example.com/chat');
// 接続が確立された時のイベント(密着開始)
socket.addEventListener('open', (event) => {
console.log('サーバーと繋がりました!');
// サーバーへメッセージを送信
socket.send('こんにちは!茶トラです!');
});
// サーバーからメッセージを受け取った時のイベント(双方向の受信)
socket.addEventListener('message', (event) => {
console.log('サーバーからの返信: ', event.data);
});
// 通信エラーや切断時のハンドリングも忘れずに実装する
socket.addEventListener('close', () => {
console.log('コネクションが切断されました。再接続を試みます...');
}); コード自体は非常にシンプルですが、「いつ通信が切れるか分からない」という前提に立ち、切断された場合の自動再接続処理や、エラーハンドリングをしっかり組み込むことがプロの現場では求められます。
🛠️ Websocketを賢く使うためのポイント
現場でWebsocketを採用・運用する際に、エンジニアが頭を悩ませる代表的なポイントとベストプラクティスです。
- ステートフルゆえの負荷とスケーリング: 繋がりっぱなし(ステートフル)であるため、アクセスが急増した際にサーバーを増やす(スケールアウト)設計が難しくなります。Redisなどの外部ストアを使って、複数サーバー間でセッション情報を共有する工夫が必要です。
- プロキシやロードバランサの設定: 中間にあるロードバランサやプロキシサーバー(Nginxなど)が、長時間続くWebsocketの通信を「タイムアウト」と勘違いして強制切断しないように、適切なタイムアウト設定やアップグレード設定を行う必要があります。
- WSS(暗号化)の必須化: 通信内容を第三者に傍受されないよう、通常の「ws://」ではなく、SSL/TLSで暗号化された「wss://」(HTTPSのWebsocket版)を必ず使用してセキュリティを担保します。
お互いの体同士をピッタリくっつけて安心して眠る茶トラとアメショのように、システム同士が安全かつ安定して繋がり続けられる環境(インフラ設定とエラー対策)を整えてあげることが、Websocketを使いこなす最大の鍵となります。