| 227 | } |
| 228 | |
| 229 | class RTCPeer extends Peer { |
| 230 | |
| 231 | constructor(serverConnection, peerId) { |
| 232 | super(serverConnection, peerId); |
| 233 | if (!peerId) return; // we will listen for a caller |
| 234 | this._connect(peerId, true); |
| 235 | } |
| 236 | |
| 237 | _connect(peerId, isCaller) { |
| 238 | if (!this._conn) this._openConnection(peerId, isCaller); |
| 239 | |
| 240 | if (isCaller) { |
| 241 | this._openChannel(); |
| 242 | } else { |
| 243 | this._conn.ondatachannel = e => this._onChannelOpened(e); |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | _openConnection(peerId, isCaller) { |
| 248 | this._isCaller = isCaller; |
| 249 | this._peerId = peerId; |
| 250 | this._conn = new RTCPeerConnection(RTCPeer.config); |
| 251 | this._conn.onicecandidate = e => this._onIceCandidate(e); |
| 252 | this._conn.onconnectionstatechange = e => this._onConnectionStateChange(e); |
| 253 | this._conn.oniceconnectionstatechange = e => this._onIceConnectionStateChange(e); |
| 254 | } |
| 255 | |
| 256 | _openChannel() { |
| 257 | const channel = this._conn.createDataChannel('data-channel', { |
| 258 | ordered: true, |
| 259 | reliable: true // Obsolete. See https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/reliable |
| 260 | }); |
| 261 | channel.onopen = e => this._onChannelOpened(e); |
| 262 | this._conn.createOffer().then(d => this._onDescription(d)).catch(e => this._onError(e)); |
| 263 | } |
| 264 | |
| 265 | _onDescription(description) { |
| 266 | // description.sdp = description.sdp.replace('b=AS:30', 'b=AS:1638400'); |
| 267 | this._conn.setLocalDescription(description) |
| 268 | .then(_ => this._sendSignal({ sdp: description })) |
| 269 | .catch(e => this._onError(e)); |
| 270 | } |
| 271 | |
| 272 | _onIceCandidate(event) { |
| 273 | if (!event.candidate) return; |
| 274 | this._sendSignal({ ice: event.candidate }); |
| 275 | } |
| 276 | |
| 277 | onServerMessage(message) { |
| 278 | if (!this._conn) this._connect(message.sender, false); |
| 279 | |
| 280 | if (message.sdp) { |
| 281 | this._conn.setRemoteDescription(new RTCSessionDescription(message.sdp)) |
| 282 | .then( _ => { |
| 283 | if (message.sdp.type === 'offer') { |
| 284 | return this._conn.createAnswer() |
| 285 | .then(d => this._onDescription(d)); |
| 286 | } |
nothing calls this directly
no outgoing calls
no test coverage detected