Skip to content

Commit 7f193b6

Browse files
committed
Don't terminate PeerConnection after moving to the failed state
1 parent 241931e commit 7f193b6

File tree

4 files changed

+59
-11
lines changed

4 files changed

+59
-11
lines changed

examples/save_to_file/lib/save_to_file/peer_handler.ex

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,16 @@ defmodule SaveToFile.PeerHandler do
133133
{:ok, state}
134134
end
135135

136+
defp handle_webrtc_msg({:connection_state_change, conn_state}, state) do
137+
Logger.info("Connection state changed: #{conn_state}")
138+
139+
if conn_state == :failed do
140+
{:stop, {:shutdown, :pc_failed}, state}
141+
else
142+
{:ok, state}
143+
end
144+
end
145+
136146
defp handle_webrtc_msg({:ice_candidate, candidate}, state) do
137147
candidate_json = ICECandidate.to_json(candidate)
138148

examples/save_to_file/priv/static/script.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ button.onclick = () => {
1818

1919
const start_connection = async (ws) => {
2020
const pc = new RTCPeerConnection(pcConfig);
21+
window.pc = pc;
22+
pc.onconnectionstatechange = () => {
23+
console.log(pc.connectionState);
24+
}
2125
pc.onicecandidate = event => {
2226
if (event.candidate === null) return;
2327

lib/ex_webrtc/dtls_transport.ex

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,12 @@ defmodule ExWebRTC.DTLSTransport do
251251

252252
@impl true
253253
def handle_cast({:send_rtp, _data}, state) do
254-
Logger.warning("Attempted to send RTP before DTLS handshake has been finished. Ignoring.")
254+
Logger.debug("Attempted to send RTP in wrong DTLS state: #{state.dtls_state}. Ignoring.")
255255
{:noreply, state}
256256
end
257257

258258
@impl true
259-
def handle_cast({:send_rtcp, data}, state) do
259+
def handle_cast({:send_rtcp, data}, %{dtls_state: :connected, ice_connected: true} = state) do
260260
case ExLibSRTP.protect_rtcp(state.out_srtp, data) do
261261
{:ok, protected} -> do_send(state, protected)
262262
{:error, reason} -> Logger.warning("Unable to protect RTCP: #{inspect(reason)}")
@@ -266,7 +266,13 @@ defmodule ExWebRTC.DTLSTransport do
266266
end
267267

268268
@impl true
269-
def handle_cast({:send_data, data}, state) do
269+
def handle_cast({:send_rtcp, _data}, state) do
270+
Logger.debug("Attempted to send RTCP in wrong DTLS state: #{state.dtls_state}. Ignoring.")
271+
{:noreply, state}
272+
end
273+
274+
@impl true
275+
def handle_cast({:send_data, data}, %{dtls_state: :connected, ice_connected: true} = state) do
270276
case ExDTLS.write_data(state.dtls, data) do
271277
{:ok, protected} -> do_send(state, protected)
272278
{:error, reason} -> Logger.warning("Unable to protect data: #{inspect(reason)}")
@@ -275,6 +281,12 @@ defmodule ExWebRTC.DTLSTransport do
275281
{:noreply, state}
276282
end
277283

284+
@impl true
285+
def handle_cast({:send_data, _data}, state) do
286+
Logger.debug("Attempted to send data in wrong DTLS state: #{state.dtls_state}. Ignoring.")
287+
{:noreply, state}
288+
end
289+
278290
@impl true
279291
def handle_cast({:set_packet_loss, value}, state) do
280292
state = %{state | packet_loss: value}
@@ -312,9 +324,13 @@ defmodule ExWebRTC.DTLSTransport do
312324
@impl true
313325
def handle_info({:ex_ice, _from, {:data, _data} = msg}, state) do
314326
case handle_ice_data(msg, state) do
315-
{:ok, state} -> {:noreply, state}
316-
# we use shutdown to avoid logging an error
317-
{:error, reason} -> {:stop, {:shutdown, reason}, state}
327+
{:ok, state} ->
328+
{:noreply, state}
329+
330+
{:error, reason} ->
331+
# See W3C WebRTC sec. 5.5.
332+
state = update_dtls_state(state, :failed)
333+
{:noreply, state}
318334
end
319335
end
320336

lib/ex_webrtc/peer_connection.ex

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ defmodule ExWebRTC.PeerConnection do
409409
410410
For more information, refer to the [RTCPeerConnection: createOffer() method](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createOffer).
411411
"""
412-
@spec create_offer(peer_connection(), restart_ice?: boolean()) ::
412+
@spec create_offer(peer_connection(), ice_restart: boolean()) ::
413413
{:ok, SessionDescription.t()} | {:error, term()}
414414
def create_offer(peer_connection, options \\ []) do
415415
GenServer.call(peer_connection, {:create_offer, options})
@@ -1186,7 +1186,8 @@ defmodule ExWebRTC.PeerConnection do
11861186
end
11871187

11881188
@impl true
1189-
def handle_cast({:send_rtp, track_id, packet, opts}, state) do
1189+
def handle_cast({:send_rtp, track_id, packet, opts}, %{conn_state: conn_state} = state)
1190+
when conn_state != :failed do
11901191
rtx? = Keyword.get(opts, :rtx?, false)
11911192

11921193
# TODO: iterating over transceivers is not optimal
@@ -1238,7 +1239,13 @@ defmodule ExWebRTC.PeerConnection do
12381239
end
12391240

12401241
@impl true
1241-
def handle_cast({:send_pli, track_id, rid}, state) do
1242+
def handle_cast({:send_rtp, _track_id, packet, opts}, state) do
1243+
{:noreply, state}
1244+
end
1245+
1246+
@impl true
1247+
def handle_cast({:send_pli, track_id, rid}, %{conn_state: conn_state} = state)
1248+
when conn_state != :failed do
12421249
state.transceivers
12431250
|> Enum.with_index()
12441251
|> Enum.find(fn {tr, _idx} -> tr.receiver.track.id == track_id end)
@@ -1265,7 +1272,13 @@ defmodule ExWebRTC.PeerConnection do
12651272
end
12661273

12671274
@impl true
1268-
def handle_cast({:send_data, channel_ref, data_type, data}, state) do
1275+
def handle_cast({:send_pli, _track_id, _rid}, state) do
1276+
{:noreply, state}
1277+
end
1278+
1279+
@impl true
1280+
def handle_cast({:send_data, channel_ref, data_type, data}, %{conn_state: conn_state} = state)
1281+
when conn_state != :failed do
12691282
{events, sctp_transport} =
12701283
SCTPTransport.send(state.sctp_transport, channel_ref, data_type, data)
12711284

@@ -1274,6 +1287,11 @@ defmodule ExWebRTC.PeerConnection do
12741287
{:noreply, %{state | sctp_transport: sctp_transport}}
12751288
end
12761289

1290+
@impl true
1291+
def handle_cast({:send_data, _channel_ref, _data_type, _data}, state) do
1292+
{:noreply, state}
1293+
end
1294+
12771295
@impl true
12781296
def handle_cast({:set_packet_loss, packet_loss}, state) do
12791297
DTLSTransport.set_packet_loss(state.dtls_transport, packet_loss)
@@ -1294,7 +1312,7 @@ defmodule ExWebRTC.PeerConnection do
12941312

12951313
if next_conn_state == :failed do
12961314
Logger.debug("Stopping PeerConnection")
1297-
{:stop, {:shutdown, :conn_state_failed}, state}
1315+
{:noreply, state}
12981316
else
12991317
{:noreply, state}
13001318
end

0 commit comments

Comments
 (0)