🧊

Chromeの76からiceConnectionStateがfailedにならない

M76は07/30にリリース予定。

いままで

たとえばこういうシナリオのとき。

  • AとBがP2Pでつなぐ
  • どこかのタイミングでAがブラウザを閉じる
    • NW断でもいいけど、なんしか切断する

そのときのB側の`iceConnectionState`の遷移はというと、

  • `disconnected`になる
    • ブラウザがしばらく待機する
    • というか途絶えた通信を少しの間は続行しようとする
  • `failed`になる

NWの寸断で`disconnected`になっても、ブラウザが自動的に復旧してくれるので、`failed`になってはじめて手動で再ネゴシエーションなりやってねっていう。

これから

というのがこれからは、

  • `disconnected`になる
    • ブラウザがしばらく待機する
    • というか途絶えた通信を少しの間は続行しようとする

ここで止まります。

何もしなければ、永遠に`disconnected`のまま。

なので`failed`を拾ってなんやかんやしてたコードは動かなくなります。

実際に挙動を見たい場合は、適当にP2Pをつないだあとで、`pfctl`でUDPを落としてみたりすればOK。

なぜなのか

これは単純で、Chromeの実装がそうなったから。

ちなみにバグ報告もされてるけど、もとに戻る気配はなさそう。

Issue 982793 - chromium - An open-source project to help move the web forward. - Monorail

IssueのTL;DR

  • Chromeは`end-of-candidates`を実装してないという前提がある
  • いままでつながってた経路は`disconnected`になったけど
  • もしかしたら他のICEの候補が与えられてそっちでつながるかも
  • なので`failed`とは言えない
  • 一方で、本当に`failed`かもしれない
  • けど、それも`failed`と言えない

`end-of-candidates`が実装されてないが故の二律背反沼にハマってる感じ。

どうするか

とりあえずの挙動としては、`iceConnectionState`ではなく`connectionState`を見ればよさそう。

`connectionState`は下層の`RTCIceTransport`と`RTCDtlsTransport`の状態を束ねたもので、こっちは`failed`になる。

そして幸か不幸か、これはChromeにのみ実装されてる!
なんだかなーという感じではあるけど・・・。