リアルタイム通信の未来:WebSockets、Server-Sent Events、そしてWebTransport

2024-04-02

WebSocketsとServer-Sent Events/EventSource:リアルタイム通信の2つの巨人

通信方向:双方向 vs 一方向

  • WebSockets: 双方向通信が可能。サーバーとクライアント間で自由にデータを送受信できます。
  • SSE/EventSource: 一方向通信のみ。サーバーからクライアントへのみデータを送信できます。

複雑性:複雑 vs シンプル

  • WebSockets: より複雑な技術。専用のAPIを使用し、サーバー側もWebSocket対応が必要です。
  • SSE/EventSource: 比較的シンプルな技術。HTML5標準のEventSource APIを使用できます。

ユースケース:双方向通信 vs 更新通知

  • WebSockets: チャット、オンラインゲーム、リアルタイム編集など、双方向通信が必要なアプリケーションに最適です。
  • SSE/EventSource: ニュースフィード、株価情報、ソーシャルメディアの更新通知など、サーバーからクライアントへの更新通知に最適です。

接続数:多数 vs 少数

  • WebSockets: ブラウザごとに接続できる数に制限がある場合があります。
  • SSE/EventSource: ブラウザごとの接続数制限は比較的緩いです。

ブラウザサポート:広く対応 vs 一部対応

  • WebSockets: 主要なブラウザで広くサポートされています。
  • SSE/EventSource: 一部の古いブラウザではサポートされていません。
要素WebSocketsSSE/EventSource
通信方向双方向一方向
複雑性複雑シンプル
ユースケース双方向通信更新通知
接続数制限あり制限少なめ
ブラウザサポート広く対応一部未対応

上記の表を参考に、ご自身のアプリケーションの要件に合わせて最適な技術を選びましょう。




WebSockets

import asyncio
import websockets

async def handler(websocket, path):
    while True:
        message = await websocket.recv()
        await websocket.send(message)

async def main():
    async with websockets.serve(handler, "localhost", 8765):
        await asyncio.Future()  # run forever

asyncio.run(main())

クライアント側 (JavaScript)

const socket = new WebSocket("ws://localhost:8765");

socket.onopen = function() {
    console.log("WebSocket connection opened");
};

socket.onmessage = function(event) {
    console.log("Received message: " + event.data);
};

socket.onclose = function() {
    console.log("WebSocket connection closed");
};

socket.send("Hello from the client!");

Server-Sent Events

サーバー側 (Python)

import time

from flask import Flask, render_template, Response

app = Flask(__name__)

@app.route("/")
def index():
    return render_template("index.html")

@app.route("/events")
def events():
    def generate():
        for i in range(10):
            time.sleep(1)
            yield "event: message {}\n\n".format(i)

    return Response(generate(), mimetype="text/event-stream")

if __name__ == "__main__":
    app.run()

クライアント側 (HTML)

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>SSE Example</title>
</head>
<body>
    <script>
        const eventSource = new EventSource("/events");

        eventSource.onmessage = function(event) {
            console.log("Received message: " + event.data);
        };
    </script>
</body>
</html>



WebSocketsとServer-Sent Events以外のリアルタイム通信方法

Long Polling

  • 概要: サーバーからの更新を定期的にポーリングすることでリアルタイム通信を実現
  • 利点: シンプルで実装が容易
  • 欠点: サーバー負荷が高くなる、ポーリング間隔によってはデータ遅延が発生する

Comet

  • 概要: Long Pollingを改良した技術。サーバーからの更新通知を受け取るまで接続を維持
  • 利点: サーバー負荷を軽減できる
  • 欠点: ブラウザによっては対応していない

WebRTC

  • 概要: 音声・ビデオ通話など、リアルタイムなメディア通信に特化
  • 利点: 低遅延、高品質な通信が可能
  • 欠点: 実装が複雑、ブラウザの互換性問題がある

WebTransport

  • 概要: WebSocketsとHTTP/3を組み合わせた新しい技術
  • 利点: WebSocketsよりも高速、低遅延、省電力
  • 欠点: ブラウザの対応状況はまだ限定的

それぞれの方法には異なる特徴と利点・欠点があります。ご自身のアプリケーションの要件に合わせて最適な方法を選びましょう。


html browser websocket


JavaScript/jQueryでフォーム送信時の動作をカスタマイズする

異なる処理を実行する ボタン1: 注文確定 ボタン2: カートに入れるボタン1: 注文確定ボタン2: カートに入れる異なるページに遷移する ボタン1: 次のステップへ進む ボタン2: キャンセルボタン1: 次のステップへ進むボタン2: キャンセル...


focus()メソッドとselect()メソッドを使ってファイル選択ダイアログを表示する

JavaScriptでは、ファイル入力要素のクリックイベントをプログラムで発生させることができます。これは、ユーザー操作なしでファイル選択ダイアログを表示したい場合などに役立ちます。方法ファイル入力要素のクリックイベントをプログラムで発生させるには、以下の2つの方法があります。...


HTMLとCSSでテーブルを水平方向に中央揃えにする方法

text-align プロパティこれは、テーブルセル内のテキストを水平方向に配置する最も簡単な方法です。上記のコードでは、text-align: center; を td セレクタに適用することで、すべてのセル内のテキストが中央揃えになります。...


jQuery入門:ラジオボタンのチェック状態を取得・変更する方法

HTMLjQueryこの方法では、:checked セレクタを使用して、選択されているラジオボタンを取得します。この方法では、prop() メソッドを使用して、ラジオボタンの checked プロパティを取得します。上記の方法のいずれかを使用して、jQueryでラジオボタンがオンかどうかを確認することができます。どの方法を使用するかは、状況によって異なります。...


さようなら「1」「2」「3」!CSSで「1.1」「1.2」形式の番号付きリストを作る方法

HTMLCSS解説counter-reset: このプロパティは、カウンター変数を定義し、初期値を設定します。上記の例では、item という名前のカウンター変数を定義し、初期値を 0 に設定しています。list-style-type: このプロパティは、リストマーカーの種類を指定します。none を指定することで、デフォルトの丸いマーカーを非表示にします。...