webとソケットの仕組みと基本を丁寧に解説する記事

目次

はじめに

本ドキュメントの目的

本書はWebSocketの基本概念から実装、活用までをわかりやすく解説します。リアルタイムで双方向の通信を行う仕組みを、技術的な流れや具体例を交えて学べます。まず全体像をつかんでから各章に進む設計です。

読者対象

エンジニア初心者から中級者を想定しています。プログラミングの基礎(HTTPの概念やクライアント/サーバーのイメージ)があると理解が速くなりますが、初めての方でも段階的に学べるよう配慮しています。

本書の読み方

各章は独立性を持ちながら順に読むと効果的です。まず第2章でWebSocketの全体像をつかみ、第4章で内部の仕組みを確認し、第6章で実際のコード例に触れてください。実例を試しながら進めると理解が深まります。

WebSocketとは何か

短い定義

WebSocketは、ブラウザとサーバー間でリアルタイムの双方向通信を可能にする仕組みです。通常のHTTPとは違い、一度接続を確立すると接続を維持したままデータをやり取りします。

なぜ使うか(イメージ)

チャットやオンラインゲーム、株価のリアルタイム表示のように、遅延なく双方から情報を送受信したい場面で使います。例えばチャットでは、相手がメッセージを送るとすぐに受信して画面に表示できます。

どのように動くか(簡単な流れ)

  1. ブラウザがサーバーに接続要求を送ります(最初はHTTPで)。
  2. サーバーが要求を受け入れると、通信がWebSocketに切り替わり接続が確立します。
  3. 接続後は、ブラウザもサーバーも自由にメッセージを送れます。

具体例

  • チャットアプリ:相手の発言をすぐに受信します。
  • スポーツのスコア配信:試合状況をリアルタイムで更新します。

注意点

常に接続を維持するため、サーバー側で管理が必要です。接続数が多いとリソースを多く使うため、設計時に考慮します。

WebSocketの基本的な特徴

双方向通信

WebSocketでは、クライアント(例:ブラウザ)とサーバーが互いに自由にデータを送受信できます。通常のHTTPのようにクライアント側からの要求待ちだけでなく、サーバー側からも必要なときに情報を送れます。チャットや通知で特に役立ちます。

リアルタイム性

接続が確立すると、メッセージの往復にかかる遅延が小さくなります。これにより、株価の更新やオンラインゲームの同期など、瞬時の反応が求められる場面に向きます。

軽量な通信

WebSocketはデータのやり取りに余分なヘッダーを繰り返し送らないため、同じ情報量でも通信量を抑えられます。短いメッセージを頻繁に送る用途で効率的です。

常時接続(持続的な接続)

一度接続すると、明示的に切断するまでその接続が維持されます。そのため、毎回接続を張り直す必要がなく、応答が速くなります。接続の管理はアプリ側で行う必要があります。

WebSocketの仕組み

1. ハンドシェイク(接続の確立)

WebSocketは最初に通常のHTTPリクエストで接続を作ります。ブラウザはGETでUpgrade: websocketやSec-WebSocket-Keyを送ります。サーバーは101 Switching Protocolsで応答し、Sec-WebSocket-Acceptを返してWebSocketへ切り替えます。具体例では、ブラウザが“この接続をWebSocketに切り替えてください”と頼み、サーバーが同意するイメージです。

2. データ転送(フルデュプレックス)

アップグレード後は双方向でいつでもデータを送れます。通信は「フレーム」と呼ばれる単位で行います。テキストやバイナリ、ping/pong、closeなどの種類(opcode)があります。クライアント側はセキュリティのためにペイロードをマスクします。小さなメッセージを頻繁に送れるため、チャットやリアルタイム通知に向いています。断片化もでき、大きなデータを分割して送ります。

3. 接続の終了

片方がCloseフレームを送ると終了手続きが始まります。相手は応答のCloseを返し、TCP接続を閉じます。これにより双方が安全に切断できます。心拍(ping/pong)で接続の生存確認を行い、応答が無ければ切断する実装が一般的です。

HTTP通信との違い

概要

WebSocketとHTTPは、同じ「ネットでデータを送る」技術でも仕組みが違います。簡単に言うと、WebSocketは一度つなげばそのまま双方向でやり取りを続けられます。一方HTTPは必要なときに都度つなぎ直してデータを取りに行く方式です。

接続の持続性

WebSocketは接続を維持します。例えると“電話”のように通話が続く状態です。HTTPはその都度つながる“手紙のやり取り”のようで、送るたびに封筒を出します。

通信の向きとタイミング

WebSocketはサーバーとクライアントの両方から自由に送信できます。チャットやオンラインゲーム、リアルタイムの通知に向きます。HTTPは基本的にクライアントが要求してサーバーが応答する一方向の流れで、Webページや画像の取得に適しています。

データ量と効率

頻繁に小さなメッセージをやりとりする場合、WebSocketはヘッダーが小さく効率的です。HTTPは毎回ヘッダーを交換するため、回数が多いと負担が大きくなります。

適した使い分け

リアルタイム性が重要ならWebSocketを選びます。ページの読み込みや一回限りのデータ取得ならHTTPで十分です。負荷や接続の管理、セキュリティの違いも考慮してください。

WebSocketの実装例

概要

Node.jsのwsモジュールを使った簡単なサーバー例です。ポート3000で待ち受け、接続・メッセージ受信・切断を処理してクライアントへ返信します。

コード例

// インストール: npm install ws
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });

wss.on('connection', (ws, req) => {
  console.log('クライアント接続:', req.socket.remoteAddress);
  ws.send('サーバーへようこそ');

  ws.on('message', (message) => {
    console.log('受信:', message.toString());
    ws.send(`受け取りました: ${message}`);
  });

  ws.on('close', (code, reason) => {
    console.log('切断:', code, reason?.toString());
  });

  ws.on('error', (err) => console.error('エラー:', err));
});

console.log('WebSocketサーバーをポート3000で起動しました');

主要な処理の説明

  • connection: 新しいクライアントが接続したときに呼ばれます。初期メッセージを送れます。
  • message: クライアントからのデータを受け取ります。テキスト・バイナリに対応します。
  • close: 切断時の後処理に使います。リソース開放やログ記録が必要なときに役立ちます。
  • error: 通信で問題が起きたときに捕捉します。

実行方法

  1. wsをインストール: npm install ws
  2. 上記をserver.jsに保存
  3. node server.jsで起動

ワンポイント(全体への送信)

全クライアントへ送るにはwss.clientsを走査します。例: wss.clients.forEach(c => c.send(‘通知’))

注意点

短い接続時や大量接続の負荷対策、メッセージサイズ上限、認証はアプリに合わせて追加してください。

WebSocketの活用場面

概要

WebSocketは双方向で継続的にデータをやり取りできるため、即時性が求められる場面でよく使われます。ここでは代表的な活用例と、どんな利点があるかを具体例で説明します。

チャット・メッセージング

ユーザー同士がリアルタイムで会話するチャットで使います。メッセージを送るとすぐ他ユーザーの画面に表示され、短い遅延で自然な会話が成り立ちます。

リアルタイム通知

注文の状況やシステムアラートなどをプッシュで通知する用途に向きます。サーバー側から積極的に情報を送れるため、ユーザーは常に最新の状態を受け取れます。

ライブデータ配信

株価やスポーツの得点、センサーの値など頻繁に更新されるデータ配信で有効です。従来の繰り返し問い合わせに比べて通信量を減らせます。

オンラインゲーム・共同編集

プレイヤーの操作やドキュメントの編集内容を即時に同期することで、遅延の少ない体験を提供します。複数人で同時に動く場面で効果を発揮します。

IoT・遠隔制御

家電やセンサーと継続的に接続し、状態監視や遠隔操作を行えます。双方向通信でコマンド送信と状態取得を同時に行えます。

実装上の注意点

常時接続のためサーバー資源を考慮する必要があります。接続管理や再接続の仕組みを用意し、負荷分散や認証も設計してください。

よかったらシェアしてね!
  • URLをコピーしました!

この記事を書いた人

目次