WebRTC リアルタイム通信実践 2026:ピア接続、SFU、本番パターン

前端工程

WebRTC が今もリアルタイム通信の基盤である理由

ビデオ会議、オンライン教育、ライブ配信のマイク接続、クラウドゲーム、IoT 遠隔制御の裏側で、WebRTC はブラウザネイティブ・低遅延・端末間暗号化の事実上の標準です。2026 年、Plan B が標準から削除され Unified Plan が完全定着、さらに insertable streams(挿入可能メディア)による端末間暗号化のカスタマイズが可能になり、本番環境での成熟度が増しています。

能力 WebRTC 従来の RTMP/HLS
遅延 100ms ~ 500ms 2s ~ 30s
暗号化 既定 DTLS-SRTP 別途設定要
ブラウザネイティブ ✅ プラグイン不要 ❌ プレーヤ要
双方向 ✅ 天然支援 ❌ 単方向主体

コア概念の全体像

  • Signaling(シグナリング):SDP と ICE 候補を交換するチャネル。WebRTC は規定せず、通常 WebSocket を使う。
  • SDP:メディア能力(コーデック、解像度、伝送アドレス)のセッション記述。
  • ICE / STUN / TURN:到達可能な経路を発見し NAT を越える。
  • PeerConnection:メディアトラックとデータ伝送を管理する中心オブジェクト。

ステップ1:ピア接続を確立する

最小の 1:1 通話骨架(シグナリングは WebSocket):

// クライアント A
const pc = new RTCPeerConnection({
  iceServers: [
    { urls: "stun:stun.l.google.com:19302" },
    { urls: "turn:turn.example.com:3478", username: "user", credential: "pass" }
  ]
});

// ローカル音声・映像を取得
const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
localStream.getTracks().forEach(track => pc.addTrack(track, localStream));

// リモートトラック到着時に描画
pc.ontrack = (e) => {
  remoteVideo.srcObject = e.streams[0];
};

// Offer を生成してシグナリングサーバへ
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
signaling.send(JSON.stringify({ type: "offer", sdp: pc.localDescription }));

シグナリングサーバ(Node + ws)は転送のみ、メディアには関与しません:

import { WebSocketServer } from "ws";
const wss = new WebSocketServer({ port: 8080 });
const peers = new Map();

wss.on("connection", (ws) => {
  ws.on("message", (msg) => {
    const data = JSON.parse(msg);
    // 単純なルーム転送:offer/answer/candidate を同室のもう一人へ
    const target = peers.get(data.room)?.find(p => p !== ws);
    target?.send(msg);
  });
});

NAT 越え:STUN と TURN の役割分担

接続失敗の多くは NAT が根因です。3 つのシナリオを理解します:

シナリオ 解決策 説明
双方が公網/錐型 NAT STUN 公網マッピングを発見すれば直結
対称型 NAT TURN リレー必須
厳格な企業 FW TURN + TLS 443 ポートでリレー
// 優先直結(p2p)、失敗時は TURN リレーへ自動退避
const pc = new RTCPeerConnection({
  iceServers: [
    { urls: "stun:stun.example.com" },
    { urls: "turn:turn.example.com:3478?transport=tcp", username: "u", credential: "c" }
  ]
});

pc.oniceconnectionstatechange = () => {
  if (pc.iceConnectionState === "disconnected") {
    console.warn("ICE 切断、再接続を試行…");
  }
};

接続調査では、まず URL 解析 ツールでシグナリング/TURN アドレス形式を確認し、HTTP ステータスコード でシグナリング健全性を照合します。


トポロジ選択:Mesh / SFU / MCU

トポロジ 原理 長所 短所 用途
Mesh 全ペア直結 中継サーバ経費なし 帯域が人数の二乗で増大 4人以下の小部屋
SFU サーバ転送・トランスコードなし 客側は1上り・多下り サーバ帯域が大 会議の主流
MCU サーバ混入 客側は1受信 サーバ CPU 高・遅延大 弱網/電話接入

2026 年、大半のビデオ会議は SFU を採用。客側は1上り(Simulcast 多段)し、他者の多下りを購読します。

// Simulcast:同一映像を3段で同時送信、SFU が購読者の網に応じ選択
const sender = pc.getSenders().find(s => s.track.kind === "video");
await sender.setParameters({
  encodings: [
    { rid: "low", maxBitrate: 150_000, scaleResolutionDownBy: 4 },
    { rid: "mid", maxBitrate: 500_000, scaleResolutionDownBy: 2 },
    { rid: "high", maxBitrate: 1_500_000 }
  ]
});

データチャネル:音声・映像だけではない

WebRTC の RTCDataChannel は低遅延・順序有無選択可能な P2P データ伝送を提供し、ゲーム状態同期、ファイル転送、ホワイトボード協調に最適です。

const dc = pc.createDataChannel("whiteboard", { ordered: false, maxRetransmits: 0 });
dc.onopen = () => dc.send(JSON.stringify({ type: "stroke", points: [...] }));
dc.onmessage = (e) => renderStroke(JSON.parse(e.data));

構造化メッセージを送る際は、先に JSON フォーマッター でペイロードを検証し、解析例外でデータチャネルが崩壊するのを防ぎます。


セキュリティ:既定暗号化も境界は守る

WebRTC メディアは既定で DTLS-SRTP 端末間暗号化ですが、「安全そのもの」ではありません:

  1. シグナリングは HTTPS/WSS 必須。さもないと SDP が中間者に改ざんされる。
  2. メディアサーバは認可を。SFU は track 加入時に room token を検証すべき。
  3. E2EE カスタムinsertable streamsRTCRtpScriptTransform)でアプリ層鍵を注入し、サーバも平文を見えない真の端末間暗号化を実現。
// パケット単位メディア暗号化(略示)
const encoder = new RTCRtpScriptTransform(pc, "https://cdn/encrypt-worker.js");
sender.transform = encoder;

本番スケールパターン

カスケード SFU(Cascading SFU)

大規模クロスリージョン会議は複数 SFU をカスケードし、近接接入・内部転送で国際遅延を下げます。

帯域推定と輻輳制御

WebRTC は GCC(Google Congestion Control)を内蔵しますが、協調が必要です:

  • pc.getStats()googAvailableSendBandwidth を監視し動的降段;
  • 弱網では不要なデータチャネルを閉じる;
  • adaptivePtime で音声パケット化時間を調整。

自動購読管理

「話している/フォーカス中」のリモート流のみ購読し、下り帯域を削減します。

function subscribeTo(userId, quality) {
  signaling.send(JSON.stringify({ type: "subscribe", userId, quality }));
}

よくある質問 FAQ

Q1:なぜ「接続中」で止まりがち?

90% は NAT/ファイアウォール起因の ICE 失敗。TURN が使えるか、シグナリングが candidate を転送しているか確認を。

Q2:Mesh と SFU はどちら?

4人以下の小部屋は Mesh でコスト節約。4人超や録画/混入が必要なら SFU 必須。

Q3:モバイルをバックグラウンドにすると切れますか?

切れます。iOS/Android はバックグラウンドで getUserMedia を凍結。 visibilitychange を監視し再接続か公開停止を。

Q4:WebRTC でライブ配信できますか?

低遅延インタラクティブ配信(マイク接続)に最適。単方向の大規模配信は SFU 出力を HLS/CMAF へ再パッケージを。

Q5:Simulcast は必須ですか?

多段 Simulcast は弱網体験を大きく改善しますが、上り帯域を約10%-20%増やします。場面で权衡を。


推奨ツール

WebRTC 開発・調査には、以下の ToolsKu ツールが役立ちます:


WebRTC の壁は「接続確立」と「NAT 越え」。この二つを越えれば、ブラウザの中にミリ秒遅延のリアルタイム世界を構築できます。

ブラウザローカルツールを無料で試す →

#WebRTC#实时通信#音视频#SFU#前端#Web开发