From 4850b5cb7cba9e36d286e08d365c7762248f4af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20=C5=A0ediv=C3=BD?= Date: Tue, 2 Feb 2021 20:27:23 +0100 Subject: [PATCH] add Trickle ICE support. --- src/component/internal/messages.ts | 5 +++++ src/component/internal/webrtc.ts | 22 ++++++++++++++++++++++ src/component/main.vue | 6 ++++++ src/component/types/events.ts | 1 + src/component/types/messages.ts | 4 ++++ 5 files changed, 38 insertions(+) diff --git a/src/component/internal/messages.ts b/src/component/internal/messages.ts index a75de5fa..64a40eef 100644 --- a/src/component/internal/messages.ts +++ b/src/component/internal/messages.ts @@ -116,6 +116,11 @@ export class NekoMessages extends EventEmitter { // TODO: Handle. } + protected [EVENT.SIGNAL_CANDIDATE]({ event, ...candidate }: message.SignalCandidate) { + this._log.debug('EVENT.SIGNAL_CANDIDATE') + // TODO: Handle. + } + ///////////////////////////// // Member Events ///////////////////////////// diff --git a/src/component/internal/webrtc.ts b/src/component/internal/webrtc.ts index d95b2e35..d128463d 100644 --- a/src/component/internal/webrtc.ts +++ b/src/component/internal/webrtc.ts @@ -13,6 +13,7 @@ export interface NekoWebRTCEvents { connected: () => void disconnected: (error?: Error) => void track: (event: RTCTrackEvent) => void + candidate: (candidate: RTCIceCandidateInit) => void } export class NekoWebRTC extends EventEmitter { @@ -40,6 +41,16 @@ export class NekoWebRTC extends EventEmitter { ) } + public async setCandidate(candidate: RTCIceCandidateInit) { + if (!this._peer) { + this._log.warn(`could not add remote ICE candidate: peer does not exist!`) + return + } + + this._peer.addIceCandidate(candidate) + this._log.debug(`adding remote ICE candidate`, candidate) + } + public async connect(sdp: string, lite: boolean, servers: string[]): Promise { this._log.info(`connecting`) @@ -68,6 +79,17 @@ export class NekoWebRTC extends EventEmitter { this._log.debug(`peer signaling state changed`, this._peer ? this._peer.signalingState : undefined) } + this._peer.onicecandidate = (event: RTCPeerConnectionIceEvent) => { + if (!event.candidate) { + this._log.debug(`sent all remote ICE candidates`) + return + } + + const init = event.candidate.toJSON() + this.emit('candidate', init) + this._log.debug(`sending remote ICE candidate`, init) + } + this._peer.oniceconnectionstatechange = (event) => { this._state = this._peer!.iceConnectionState this._log.debug(`peer ice connection state changed: ${this._peer!.iceConnectionState}`) diff --git a/src/component/main.vue b/src/component/main.vue index 1f8d69eb..e64e0ac0 100644 --- a/src/component/main.vue +++ b/src/component/main.vue @@ -320,6 +320,9 @@ this.websocket.send('signal/answer', { sdp }) } catch (e) {} break + case 'signal/candidate': + this.webrtc.setCandidate(payload) + break } }) this.websocket.on('connecting', () => { @@ -356,6 +359,9 @@ this._video.play() } }) + this.webrtc.on('candidate', (candidate: RTCIceCandidateInit) => { + this.websocket.send('signal/candidate', candidate) + }) this.webrtc.on('connecting', () => { Vue.set(this.state.connection, 'webrtc', 'connecting') this.events.emit('connection.webrtc', 'connecting') diff --git a/src/component/types/events.ts b/src/component/types/events.ts index 438407bc..7c3f4ed1 100644 --- a/src/component/types/events.ts +++ b/src/component/types/events.ts @@ -5,6 +5,7 @@ export const SYSTEM_DISCONNECT = 'system/disconnect' export const SIGNAL_REQUEST = 'signal/request' export const SIGNAL_ANSWER = 'signal/answer' export const SIGNAL_PROVIDE = 'signal/provide' +export const SIGNAL_CANDIDATE = 'signal/candidate' export const MEMBER_CREATED = 'member/created' export const MEMBER_DELETED = 'member/deleted' diff --git a/src/component/types/messages.ts b/src/component/types/messages.ts index 55d28f01..94981c42 100644 --- a/src/component/types/messages.ts +++ b/src/component/types/messages.ts @@ -39,6 +39,10 @@ export interface SignalProvide { ice: string[] } +export interface SignalCandidate extends RTCIceCandidateInit { + event: string | undefined +} + export interface SignalAnswer { event: string | undefined sdp: string