# `Membrane.WebRTC.Signaling`
[🔗](https://github.com/membraneframework/membrane_webrtc_plugin/blob/v0.26.7/lib/membrane_webrtc/signaling.ex#L1)

Signaling channel for sending WebRTC signaling messages between Membrane elements
and other WebRTC peers.

The flow of using the signaling channel is the following:
- Create it with `new/0`.
- Register the peer process (the one to send and receive signaling messages)
  with `register_peer/2`.
- Pass the signaling to `Membrane.WebRTC.Source` or `Membrane.WebRTC.Sink` (this
  can also be done before the call to `register_peer/2`).
- Send and receive signaling messages. Messages can be sent by calling `signal/2`.
  The signaling channel sends `t:message/0` to the peer.

# `ex_webrtc_message`

```elixir
@type ex_webrtc_message() ::
  ExWebRTC.ICECandidate.t() | ExWebRTC.SessionDescription.t()
```

Messages sent and received if `message_format` is `ex_webrtc`.

# `json_data_message`

```elixir
@type json_data_message() :: %{required(String.t()) =&gt; term()}
```

Messages sent and received if `message_format` is `json_data`.

The keys and values are the following
- `%{"type" => "sdp_offer", "data" => data}`, where data is the return value of
  `ExWebRTC.SessionDescription.to_json/1` or `RTCPeerConnection.create_offer` in the JavaScript API
- `%{"type" => "sdp_answer", "data" => data}`, where data is the return value of
  `ExWebRTC.SessionDescription.to_json/1` or `RTCPeerConnection.create_answer` in the JavaScript API
- `%{"type" => "ice_candidate", "data" => data}`, where data is the return value of
  `ExWebRTC.ICECandidate.to_json/1` or `event.candidate` from the `RTCPeerConnection.onicecandidate`
  callback in the JavaScript API.

# `message`

```elixir
@type message() ::
  {:membrane_webrtc_signaling, pid(), message_content(), metadata :: map()}
```

Messages sent by the signaling channel to the peer.

# `message_content`

```elixir
@type message_content() :: ex_webrtc_message() | json_data_message()
```

Messages that the peer sends with `signal/2` and receives in `t:message/0`.

If the `message_format` of the peer is `ex_webrtc` (default), they should be
`t:ex_webrtc_message/0`.
If the `message_format` is `json_data`, they should be `t:json_data_message/0`.

The `message_format` of the peer can be set in `register_peer/2`.

# `t`

```elixir
@type t() :: %Membrane.WebRTC.Signaling{pid: pid()}
```

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `close`

```elixir
@spec close(t()) :: :ok
```

# `new`

```elixir
@spec new() :: t()
```

Spawns Signaling GenServer and wraps it in a struct.

Be aware that the GenServer is not started under any supervision tree, so it needs to be manually
stopped.

# `new`

```elixir
@spec new(pid()) :: t()
```

Wraps spawned Signaling GenServer in a struct.

Added as a quick fix, earlier implementation of `new/0` always started a Signaling GenServer
beyond any supervision tree, which led to having orphaned processes.

# `register_peer`

```elixir
@spec register_peer(t(), message_format: :ex_webrtc | :json_data, pid: pid()) :: :ok
```

Registers a process as a peer, so that it can send and receive signaling messages.

Options:
- `pid` - pid of the peer, `self()` by default
- `message_format` - `:ex_webrtc` by default, see `t:message_content/0`

See the moduledoc for details.

# `signal`

```elixir
@spec signal(t(), message_content(), metadata :: map()) :: :ok
```

Sends a signaling message to the signaling channel.

The calling process must be previously registered with `register_peer/2`.
See the moduledoc for details.

# `start`

```elixir
@spec start() :: t()
```

Spawns Signaling GenServer and wraps it in a struct, without linking to the caller.

Be aware that the GenServer is not started under any supervision tree, so it needs to be manually
stopped or monitored.

# `start_link`

```elixir
@spec start_link(term()) :: GenServer.on_start()
```

Starts and links a Signaling GenServer.

Returned pid should be passed to `new/1`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
