WebSocketとは?リアルタイム通信の仕組みを基礎から理解する

💻その他

こんにちは、とまだです。

チャットアプリで相手のメッセージが瞬時に表示されるのを見て、「どうやって実現しているんだろう?」と思ったことはありませんか?

実は、この仕組みの裏側にはWebSocketという技術が使われています。

今回は、リアルタイム通信を可能にするWebSocketについて、基礎から順を追って解説します。

WebSocketとは?電話みたいな通信方法

WebSocketを理解するには、まず従来の通信方法との違いを知ることが大切です。

従来のHTTP通信は「手紙」のような仕組み

通常のWebサイトは、HTTP通信を使っています。

これは手紙のやりとりに似ています。

クライアント(ブラウザ)が手紙を送って、サーバーが返事を書く。

一通のやりとりが終わったら、また新しい手紙を送る必要があります。

WebSocketは「電話」のような仕組み

一方、WebSocketは電話のような仕組みです。

一度つながったら、お互いに好きなタイミングで話せます。

相手が話している最中でも、こちらから話しかけることができる。

これが双方向通信の本質です。

なぜWebSocketが必要なのか

リアルタイム性が求められる場面

オンラインゲームやチャットアプリでは、情報の即時性が重要です。

例えば、友達がメッセージを送った瞬間に届かないと、会話が成り立ちません。

HTTPで同じことをしようとすると、何度も「新しいメッセージある?」と聞き続ける必要があります。

これでは通信量も増えますし、サーバーの負担も大きくなってしまいます。

サーバーからの自発的な通知

株価の変動や災害情報など、サーバー側から即座に通知したい情報もあります。

HTTPではクライアントが聞いてこない限り、サーバーは情報を送れません。

WebSocketなら、重要な情報が発生した瞬間に通知できます。

WebSocketが活躍する具体的な場面

チャットアプリ

LINEやSlackのようなチャットアプリは、WebSocketの代表的な活用例です。

メッセージを送信すると、接続している全員に即座に配信されます。

「既読」機能も、WebSocketを使えば簡単に実装できます。

オンライン対戦ゲーム

格闘ゲームやFPSなど、リアルタイムの対戦が必要なゲームでも活用されています。

プレイヤーの操作が相手の画面に即座に反映される必要があるからです。

0.1秒の遅延が勝敗を分けることもあります。

共同編集ツール

Google DocsやFigmaのような共同編集ツールもWebSocketを使っています。

誰かが文字を入力したり、図形を動かしたりすると、他の人の画面にも反映されます。

まるで同じ画面を見ているような体験が可能になります。

WebSocketの基本的な仕組み

接続の流れ

WebSocketの接続は、3つの段階で成立します。

  1. ハンドシェイク: HTTPで「WebSocketで通信したい」と申し出る
  2. 接続確立: サーバーがOKを出したら専用の通信路が開通
  3. データ交換: 自由にメッセージをやりとり

電話で例えると、番号をダイヤルして、相手が出たら会話が始まる感じです。

接続が切れたときの対処

ネットワークの不調などで接続が切れることもあります。

そんなときは自動的に再接続する仕組みを入れておくと便利です。

電話が切れたら、もう一度かけ直すイメージですね。

実装してみよう:シンプルなチャット

サーバー側の実装(Node.js)

まずはサーバー側から作ってみましょう。

// WebSocketライブラリをインポート
const WebSocket = require('ws');

// ポート3000でサーバーを起動
const server = new WebSocket.Server({ port: 3000 });

// クライアントが接続してきたときの処理
server.on('connection', (ws) => {
  console.log('新しいユーザーが参加しました');

  // メッセージを受信したときの処理
  ws.on('message', (message) => {
    // 接続している全員にメッセージを送信
    server.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(`${message}`);
      }
    });
  });
});

このコードは、チャットルームのような役割を果たします。

誰かがメッセージを送ると、参加者全員に配信される仕組みです。

クライアント側の実装(HTML + JavaScript)

次に、ブラウザで動くクライアント側を作ります。

<!DOCTYPE html>
<html>
<head>
  <title>シンプルチャット</title>
  <style>
    #messages {
      height: 300px;
      border: 1px solid #ccc;
      overflow-y: scroll;
      padding: 10px;
    }
  </style>
</head>
<body>
  <div id="messages"></div>
  <input type="text" id="input" placeholder="メッセージを入力">
  <button id="send">送信</button>

  <script>
    // WebSocket接続を作成
    const ws = new WebSocket('ws://localhost:3000');

    // 接続が成功したとき
    ws.onopen = () => {
      addMessage('チャットルームに接続しました');
    };

    // メッセージを受信したとき
    ws.onmessage = (event) => {
      addMessage(event.data);
    };

    // 送信ボタンをクリックしたとき
    document.getElementById('send').onclick = () => {
      const input = document.getElementById('input');
      if (input.value) {
        ws.send(input.value);
        input.value = '';
      }
    };

    // メッセージを画面に表示する関数
    function addMessage(text) {
      const messages = document.getElementById('messages');
      const div = document.createElement('div');
      div.textContent = text;
      messages.appendChild(div);
      messages.scrollTop = messages.scrollHeight;
    }
  </script>
</body>
</html>

このHTMLファイルを開けば、簡単なチャットアプリの完成です。

複数のブラウザタブで開いて試してみると、メッセージがリアルタイムで共有されることが確認できます。

よくある質問と注意点

セキュリティは大丈夫?

WebSocketも通常のWeb通信と同じく、セキュリティ対策が必要です。

特に重要なのは以下の3点です。

  • 認証: 誰でも接続できないように、ユーザー認証を実装する
  • 暗号化: wss://(WebSocket Secure)を使って通信を暗号化する
  • 入力検証: 送信されたデータが安全かチェックする

大量のユーザーに対応できる?

ユーザー数が増えると、サーバーの負荷も増えます。

対策としては、以下のような方法があります。

  • 複数のサーバーに負荷を分散する
  • 必要のない接続は適切に切断する
  • メッセージの送信頻度を制限する

古いブラウザでも動く?

最近のブラウザはほぼ対応していますが、古いブラウザでは動かないことがあります。

そんなときは、Socket.IOのようなライブラリを使うと便利です。

WebSocketが使えない環境では、自動的に別の方法で通信してくれます。

実践的な活用のヒント

再接続の実装

ネットワークが不安定な環境でも使えるように、再接続機能は重要です。

let ws;
let reconnectInterval = 5000; // 5秒後に再接続

function connect() {
  ws = new WebSocket('ws://localhost:3000');

  ws.onclose = () => {
    console.log('接続が切れました。再接続します...');
    setTimeout(connect, reconnectInterval);
  };

  // その他の処理...
}

connect();

このように実装すれば、接続が切れても自動的に復帰します。

メッセージの種類を分ける

チャットメッセージ、システム通知、エラーなど、メッセージの種類を分けると便利です。

// JSONでメッセージを送信
ws.send(JSON.stringify({
  type: 'chat',
  text: 'こんにちは',
  timestamp: Date.now()
}));

受信側でtypeを見て、処理を分岐させることができます。

まとめ

WebSocketは、リアルタイム通信を実現する強力な技術です。

HTTPの「手紙」から、WebSocketの「電話」への進化。

この違いを理解すれば、どんな場面で使うべきかが見えてきます。

チャットアプリから始めて、徐々に複雑な機能を追加していく。

そうすることで、WebSocketの可能性を実感できるはずです。

まずは今回紹介したシンプルなチャットを動かしてみてください。

リアルタイムでメッセージが届く瞬間を体験すれば、WebSocketの魅力がきっと伝わるはずです。

共有:

著者について

とまだ

とまだ

フルスタックエンジニア

Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。

著者の詳細を見る →