I'm attempting to detect when the other side of a RTCPeerConnection has disconnected. Currently I'm doing the following with my RTCPeerConnection object:
rtcPeerConnection.oniceconnectionstatechange = () => {
const state = rtcPeerConnection.iceConnectionState;
if (state === "failed" || state === "closed") {
// connection to the peer is lost and unsalvageable, run cleanup code
} else if (state === "disconnected") {
// do nothing in the "disconnected" state as it appears to be a transient
// state that can easily return to "connected" - I've seen this with Firefox
}
};
This seems to work in my limited testing with very simply network conditions but the following from MDN gives me pause that it's probably not going to hold up in production:
Of course, "disconnected" and "closed" don't necessarily indicate errors; these can be the result of normal ICE negotiation, so be sure to handle these properly (if at all).
Should I instead be using RTCPeerConnection.onconnectionstatechange
and considering the connection permanently closed if RTCPeerConnection.connectionState
is "closed"
, "failed"
or "disconnected"
?
The specification has very carefully crafted advice on that topic:
Performing an ICE restart is recommended when
iceConnectionState
transitions to"failed"
. An application may additionally choose to listen for theiceConnectionState
transition to"disconnected"
and then use other sources of information (such as usinggetStats
to measure if the number of bytes sent or received over the next couple of seconds increases) to determine whether an ICE restart is advisable.
See the spec and the PR that added this
Mind you that due to bugs Chrome no longer goes to "failed" in unified plan. "closed" can only happen if your code calls pc.close() so is no longer fired in iceconnectionstatechange as of Chrome 80.