# WebRTC Connection Tester

> WebRTCをブラウザ内で診断：ICE候補の平易な解説、NATタイプ検出、UDPブロック確認、TURNサーバー検証、2ブラウザ間の実P2Pテスト。

- URL: https://bytescope.dev/ja/webrtc-test/
- Locale: ja · Also: [en](https://bytescope.dev/en/webrtc-test.md) · [zh-Hant](https://bytescope.dev/zh-Hant/webrtc-test.md)
- Runs: ファイルはブラウザから送信されません — 処理はすべてローカルで行われます。
- Requires: Any modern browser (Chrome, Edge, Firefox, Safari), desktop and mobile.
- Updated: 2026-09-08

## What it does

ローカル診断はページを開いた瞬間に実行されます：複数の公開STUNサーバーからICE候補が収集され、host・server-reflexive・relayに分類され、それぞれにその存在が何を意味するかの1行説明が付きます。2つの異なるSTUNサーバーがマッピングした公開ポートを比較することで、ツールはNATタイプを検出します：コーンNATはP2Pに適していますが、対称型（symmetric）NATは直接接続がしばしば失敗しTURNが必要であることを意味します — WebRTCデバッグで最も役立つ一文を、平易に述べたものです。server-reflexive候補がまったくない場合は、ネットワークがUDPをブロックしている（企業ネットワークで一般的）ことを意味し、診断はそう告げます。続いてループバックテストが、ページ内で実際に2つのpeer connectionを接続し、実際のDataChannelのスループットとレイテンシを測定します。

TURN検証機能は、WebRTC開発者が探し続けている機能です：turn:/turns:のURLと認証情報を入力すると、ツールはrelayのみの接続を強制し、お使いのTURNサーバーが実際にアロケーションを行うかを証明します — UDP、TCP、TLSの各トランスポートを個別にテストし、失敗の原因を診断します（認証情報の誤りか、ファイアウォールか、DNSか）。relay強制のスループットテストは、お使いのTURNサーバーが実際にどれだけの帯域を提供できるかを測定します — リレー経由の映像がきれいに見えるかを決める数値であり、ほとんどのツールが測定しないものです。

2ブラウザ間の接続が確立すれば、診断以外にも使えます：暗号化されたDataChannelを通じて、任意のサイズのファイルをブラウザからブラウザへ直接送信できます — バックプレッシャー付きのチャンク転送で、両側にライブの進捗と速度が表示され、データをサーバー（当サイトのものも、他の誰のものも）が保持することは一切ありません。また、接続ブロブをデバイス間でコピペする代わりにQRコードとして表示でき — 長いofferは自動循環する短いフレーム列に分割されます — BarcodeDetector APIをサポートするブラウザでは内蔵のカメラスキャナーで読み取れます。

すべてブラウザ内で動作します。接続テストはあなたが選んだSTUN/TURNサーバーとのみ通信し、ネットワークに関する情報が当サイトに送信されることはありません。

## Limits

Does not diagnose a specific video-call app's servers; it tests STUN/TURN reachability and the peer connection this browser can make.

## Machine output

Copy JSON copies an envelope `{ tool, url, generatedAt, userAgentHint, result }`. `tool` is `"webrtc-test"`; `result` is the ICE / loopback / TURN snapshot below. Candidate addresses, URLs, usernames, and credentials are omitted.

- `mode` (string | null) — `"local"` | `"turn"` | `"p2p"`. `null` = mode not set.
- `rtcPeerConnectionAvailable` (boolean | null) — `null` = not probed; `false` = probed, `RTCPeerConnection` missing; `true` = constructor exists.
- `iceGatheringOutcome` (string) — `"not-run"` | `"running"` | `"timeout"` | `"complete"`.
- `iceGatheringMs` (number | null) — Max gathering duration in ms. `null` = gathering not finished and not running, or there was no candidate source to measure.
- `hostCandidateCount` (number | null) — Count of host candidates. `null` = gathering not finished or no candidate source (could not measure).
- `srflxCandidateCount` (number | null) — Count of srflx candidates. `null` = gathering not finished or no candidate source.
- `prflxCandidateCount` (number | null) — Count of prflx candidates. `null` = gathering not finished or no candidate source.
- `relayCandidateCount` (number | null) — Count of relay candidates. `null` = gathering not finished or no candidate source.
- `udpCandidateCount` (number | null) — Count of UDP candidates. `null` = gathering not finished or no candidate source.
- `tcpCandidateCount` (number | null) — Count of TCP candidates. `null` = gathering not finished or no candidate source.
- `tcpTypes` (string[]) — Distinct `tcptype` tokens, sorted. Empty when none observed or gathering was not counted.
- `ipv4CandidateCount` (number | null) — Count of IPv4 candidates. `null` = gathering not finished or no candidate source.
- `ipv6CandidateCount` (number | null) — Count of IPv6 candidates. `null` = gathering not finished or no candidate source.
- `mdnsCandidateCount` (number | null) — Count of mDNS candidates. `null` = gathering not finished or no candidate source.
- `gotSrflx` (boolean | null) — `null` = gathering not finished; `true` = at least one srflx candidate; `false` = finished, none.
- `gotRelay` (boolean | null) — `null` = gathering not finished; `true` = at least one relay candidate; `false` = finished, none.
- `defaultStunServerCount` (number) — How many built-in STUN servers this run used. 0 in turn mode.
- `customIceServerCount` (number) — 1 when a custom TURN URL was configured, else 0. The URL itself is omitted.
- `usingDefaultStunServers` (boolean) — `false` in turn mode; `true` otherwise.
- `natKind` (string | null) — `"cone"` | `"symmetric"` | `"indeterminate"` | `"udp-blocked"`. `null` = NAT not judged (not run, or not local mode).
- `loopbackOutcome` (string) — `"not-run"` | `"running"` | `"timeout"` | `"failed"` | `"ok"`.
- `loopbackSetupMs` (number | null) — Loopback setup duration in ms. `null` = not measured.
- `loopbackPingMedianMs` (number | null) — Median loopback ping in ms. `null` = not measured.
- `loopbackThroughputAvgMbps` (number | null) — Average loopback throughput in Mbps. `null` = not measured.
- `iceErrorCode` (number | null) — First numeric ICE/TURN error code. `null` = none observed.
- `selectedPairLocalType` (string | null) — Selected ICE pair local type: `"host"` | `"srflx"` | `"prflx"` | `"relay"`. `null` = not observed.
- `selectedPairRemoteType` (string | null) — Selected ICE pair remote type, same tokens. `null` = not observed.
- `iceConnectionRoute` (string | null) — `"direct"` | `"relayed"` | `"unknown"`. `null` = route not judged.
- `turnTransports` (array of objects) — Per-transport TURN probes. Empty outside turn mode. Each item: `transport` (variant label such as udp/tcp/tls, never a URL), `gotRelay` (boolean or `null` when that variant did not report), `gatheringMs` (number or `null` when not measured), `gatheringOutcome` (`"not-run"` | `"running"` | `"timeout"` | `"complete"`), `iceErrorCode` (number or `null` when that variant had no numeric error).

## FAQ

### host / srflx / relay の各候補は何を意味しますか？

WebRTCが試せるアドレスです：host = ローカルインターフェースのアドレス（モダンブラウザではmDNSで難読化されます）、srflx = STUNサーバーから見たあなたの公開アドレス（その存在はNATを越えられることを意味します）、relay = 直接経路が失敗したときにトラフィックを転送するTURNサーバー上のアドレスです。健全な構成ではhost + srflxが表示され、relayはTURNを設定したときにのみ現れます。

### 対称型（symmetric）NATとは何で、なぜP2Pを壊すのですか？

対称型NATは、通信する宛先ごとに異なる公開ポートを割り当てるため、STUNサーバーが観測したポートは実際のピアには役立ちません — ホールパンチングが失敗します。ツールは2つのSTUNサーバーからのマッピングを比較してこれを検出します：ポートが異なれば対称型です。対称型NAT同士のピアは、事実上ほぼ常にTURNリレーが必要です。

### TURNサーバーがrelay候補を返さないのはなぜですか？

検証機能は原因を切り分けます：401 / 認証情報の失敗（ユーザー名・パスワードの誤り、または期限切れの時間制限付き認証情報）、アロケーションの失敗（サーバーに到達できない — ファイアウォールがポートをブロック、またはポート/トランスポートの誤り）、あるいはホスト名のDNS失敗です。UDP、TCP、TLSを個別にテストしてください — 企業ネットワークは443番のturns:のみを許可することがよくあります。

### これはインターネット接続の速度テストですか？

いいえ — そしてページはそれを正直に述べています。スループットの数値はWebRTCの経路を測定します：お使いのマシンのWebRTCスタック（ループバック）、お使いのTURNサーバーの容量（relay強制）、または特定のピアツーピアリンクです。一般的なダウンロード/アップロード速度テストには専用のテストサーバーが必要で、サーバーレスのサイトが誠実に提供できるものではありません。

### 2ブラウザ間テストは何をしますか？

シグナリングサーバーを一切使わずに、2台のデバイス間で実際のWebRTC接続を構築します：一方がoffer（オファー）を圧縮テキストのブロブとして作成し、それを任意のメッセンジャーで送り、もう一方がanswer（アンサー）を貼り返すと、接続が確立します — そしてライブ統計が、直接接続かリレー経由か、往復時間、ビットレート、パケットロスを表示します。WebRTCシグナリングの仕組みのデモであると同時に、2つの実ネットワーク間の本物の接続性テストでもあります。

### ファイル転送は本当にプライベートですか？どのくらいの大きさまで送れますか？

ファイルはWebRTCの暗号化されたDataChannel（DTLS）を通じてブラウザからブラウザへ送られます — アップロードの工程がなく、漏洩したり期限切れになったりするサーバー上のコピーも存在しません。直接接続なら、データは2台のマシン間の経路から一切出ません（リレー経由の接続はお使いのTURNサーバーを通りますが、暗号化されたままです）。ファイルは64 KBのチャンクでバックプレッシャー付きで送信されるため、サイズの上限は転送自体ではなく受信側ブラウザのメモリ（保存前にそこでファイルが組み立てられます）で決まります — 数百メガバイトは日常的に扱えます。

### QRコード交換はどのように動作しますか？なぜ複数フレームなのですか？

圧縮されたofferブロブは約1,900文字です — 技術的には1つのQRコードに収まりますが、それほど密度の高いコードは画面からのスキャンに失敗しがちです。そのため長いブロブは、パート表示付きで自動的に循環する、読み取りやすい短いコードの列として表示されます。スキャナーはフレームを任意の順序で収集してブロブを再構築します。読み取りにはブラウザネイティブのBarcodeDetector API（ChromeとEdge）を使います — 未対応のブラウザでは、スマートフォンのカメラアプリでスキャンするか、常に機能するコピペにフォールバックしてください。
