🌐

WebSocket とは?簡単な説明から技術的な仕組みまで

2024/10/08に公開

0. はじめに

WebSocket は、クライアント(例:ブラウザ)とサーバー間の双方向通信を可能にするプロトコルです。通常の HTTP 通信とは異なり、WebSocket ではクライアントとサーバーが常に接続された状態で通信を行い続けることができるため、リアルタイムなやりとりが求められるアプリケーションに向いています。例えば、チャットアプリや株価情報のリアルタイム更新、オンラインゲームなどに活用されています。

本記事では、WebSocket がどのように動作するのか、その技術的な詳細やユースケース、導入方法について解説していきます。


1. WebSocket の基本的な仕組み

WebSocket の概要

WebSocket は、クライアントとサーバー間の双方向通信を提供するために設計されたプロトコルです。従来の HTTP プロトコルでは、クライアントからサーバーへのリクエストに対してサーバーがレスポンスを返すという一方向通信が一般的ですが、WebSocket では常に接続を維持し、双方向のデータ送受信が可能です。

なぜ WebSocket が必要なのか?

従来の HTTP 通信は「リクエスト・レスポンス型」です。つまり、クライアントがリクエストを送信し、それに対してサーバーがレスポンスを返すという流れです。しかし、この形式ではサーバーがクライアントに一方的にデータを送信することが難しいため、例えばリアルタイムな通知機能やチャットアプリケーションには不向きです。これを補うために、ポーリング(クライアントが一定の間隔でサーバーにリクエストを送り、最新のデータを取得する方法)や長いリクエスト( Long Polling )と呼ばれる技術が使われることがありますが、これらの手法はサーバーやネットワークに負荷をかけることがあります。

WebSocket を使用すると、接続が維持された状態でクライアントとサーバーが自由にデータをやり取りできるため、リアルタイムの通信が必要なアプリケーションに最適です。

WebSocket の接続フロー

  1. ハンドシェイク(クライアントとサーバーが双方向通信を開始するために行う初期の接続確認手続き)
    WebSocket は最初に HTTP リクエストを使ってサーバーと「ハンドシェイク」を行います。クライアントがサーバーに接続リクエストを送り、サーバーがそれに応答します。この応答が成功すると、通常の HTTP 接続が WebSocket 接続に切り替わり、双方向通信が開始されます。

    例:ハンドシェイク時のHTTPヘッダー

    GET /chat HTTP/1.1
    Host: server.example.com
    Upgrade: websocket
    Connection: Upgrade
    Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
    Sec-WebSocket-Version: 13
    
  2. データフレーム(行と列を持つ表形式のデータを扱うためのデータ構造)のやりとり
    接続が確立されると、クライアントとサーバーは「データフレーム」という形式でメッセージをやり取りします。これにより、双方向のデータ送受信が可能となります。

  3. 接続の維持と終了
    WebSocket 接続は、サーバーまたはクライアントが接続を明示的に切断するまで続きます。通常の HTTP 通信ではリクエストが完了すると接続が切断されますが、WebSocket では通信を続けることが前提です。


2. WebSocket の技術的特徴

低レイテンシ

WebSocket の最大の利点の一つは低レイテンシ(遅延が少ない)な通信ができる点です。通常の HTTP ではリクエストごとに接続が確立されてからデータが送受信されますが、WebSocket では一度接続が確立されれば、その後の通信に再接続の必要がありません。このため、リアルタイム性が求められるアプリケーションにおいて、WebSocket は非常に有効です。

通信の効率性

WebSocket では、データフレームのヘッダーが非常に小さいため、従来の HTTP 通信に比べて通信のオーバーヘッドが少なくなります。これは、頻繁に小さなデータを送受信するアプリケーション、例えばゲームやチャットにおいて、特に重要です。

継続的な接続

通常の HTTP 通信では、クライアントからのリクエストに対してサーバーがレスポンスを返し、その後接続は切断されます。しかし、WebSocket では接続が持続されるため、サーバーからクライアントへの通知やメッセージのプッシュが可能になります。この機能は、チャットアプリやリアルタイム通知システムに特に適しています。

バイナリデータのサポート

WebSocket は、テキストだけでなくバイナリデータ( 0 と 1 の二進数で表されるデータ形式)も送受信することができます。これにより、画像や動画、音声データの送信が必要なアプリケーションでも活用可能です。


3. WebSocket のユースケース

チャットアプリ

WebSocket は、双方向かつリアルタイムな通信を可能にするため、チャットアプリケーションには最適です。ユーザーがメッセージを送信すると、即座にサーバーに送られ、他のユーザーにリアルタイムで表示されます。HTTP 通信のように新しいリクエストを都度送信する必要がないため、効率的です。

リアルタイムデータのストリーミング

株価や仮想通貨の価格、スポーツのスコアなど、リアルタイムで変化するデータを表示するアプリケーションにも WebSocket はよく使われます。サーバーが最新のデータをプッシュし、クライアント側はそれを即座に受信・表示できます。

オンラインゲーム

オンラインゲームでは、プレイヤーのアクションを即座にサーバーに伝え、他のプレイヤーにもリアルタイムで共有する必要があります。WebSocket を使うことで、ゲームの動作がスムーズになり、プレイヤー同士のインタラクションがリアルタイムで行えます。

IoT (モノのインターネット)

IoT デバイスは、センサー(環境の変化を感知してデータとして取得する装置)から得られるデータをリアルタイムで送信し、管理者がそれをモニタリングするという用途が一般的です。WebSocket は、この種のリアルタイムデータ通信に非常に適しています。


4. WebSocket の導入方法

実際に WebSocket を使用するためのコード例を紹介します。JavaScript を使ってクライアント側から WebSocket を実装する場合、以下のように簡単に通信を開始できます。

クライアント側のコード例( JavaScript )

// WebSocket オブジェクトを作成
let socket = new WebSocket("ws://example.com/socket");

// 接続が確立されたときの処理
socket.onopen = function(event) {
    console.log("WebSocket connection established.");
    socket.send("Hello Server!"); // サーバーにメッセージを送信
};

// メッセージを受信したときの処理
socket.onmessage = function(event) {
    console.log("Message from server: " + event.data);
};

// 接続が閉じられたときの処理
socket.onclose = function(event) {
    console.log("WebSocket connection closed.");
};

// エラーが発生したときの処理
socket.onerror = function(error) {
    console.log("WebSocket error: " + error.message);
};

サーバー側のコード例( Node.js + ws ライブラリ)

Node.js を使ったサーバーサイドでの WebSocket の実装例を紹介します。Node.jsでは "ws" というライブラリを使って簡単に WebSocket サーバーを構築できます。

const WebSocket = require('ws');

// WebSocket サーバーを作成
const wss = new WebSocket.Server({ port: 8080 });

// 接続が確立されたときの処理
wss.on('connection', function connection(ws) {
    console.log('Client connected');

    // メッセージを受信したときの処理
    ws.on('message', function incoming(message) {
        console.log('Received: %s', message);
        ws.send('Hello Client!'); // クライアントにメッセージを送信
    });

    // 接続が閉じられたときの処理
    ws.on('close', function close() {
        console.log('Client disconnected');
    });
});

5. WebSocket のメリットとデメリット

メリット

  • リアルタイム性: WebSocket は低レイテンシでデータをリアルタイムに送受信できます。
  • 双方向通信: サーバーからクライアントへ、クライアントからサーバーへ、双方向でデータをやり取りできるため、双方向のやり取りが必要なアプリケーションに最適です。
  • 効率的な通信: WebSocket は最初のハンドシェイク後、接続を維持するため、従来の HTTP 通信よりも効率的です。
  • バイナリデータ対応: テキストだけでなく、バイナリデータの送受信も可能です。

デメリット

  • 複雑な実装: HTTP と比較して接続の維持やエラーハンドリングが複雑になることがあります。
  • セキュリティリスク: WebSocket の接続は常に開かれているため、適切にセキュリティ対策を施さないと攻撃の対象になりやすいです。

6. WebSocket と他のリアルタイム通信技術との比較

WebSocket vs HTTP Polling

HTTP Polling(クライアントが定期的にサーバーにリクエストを送ってデータを取得する手法)は、定期的にクライアントからサーバーにリクエストを送信し、最新の情報を取得する手法です。WebSocket は、Polling よりも効率的でリアルタイム性が高いため、頻繁にデータをやり取りする場合に有利です。

WebSocket vs Server-Sent Events (SSE)

Server-Sent Events (SSE : サーバーからクライアントに一方向でデータをストリーム送信する技術)は、サーバーからクライアントに一方向のデータストリーム(連続的に送受信されるデータの流れ)を送る技術です。WebSocket は双方向の通信をサポートしているため、クライアントからサーバーへもデータを送信できる点で SSE と異なります。


まとめ

WebSocket は、双方向かつリアルタイムな通信を実現するための強力なプロトコルです。チャットアプリ、オンラインゲーム、リアルタイムデータのストリーミングなど、多くのユースケースで WebSocket は非常に有用です。

Discussion