UNPKG

stalk-js-webrtc

Version:

S-Talk web-rtc javascript client implementation.

194 lines (193 loc) 8.55 kB
/** * S-TAlK React-Native webrtc peer implementation... * * Copyright 2017 Ahoo Studio.co.th. */ var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { EventEmitter } from 'events'; import { RTCPeerConnection, RTCIceCandidate, RTCSessionDescription, } from 'react-native-webrtc'; import { AbstractPeerConnection } from "../core/AbstractPeerConnection"; import { AbstractPeer } from "../core/AbstractPeer"; var Peer = /** @class */ (function (_super) { __extends(Peer, _super); /** * reture PeerConnection * @param socket * @param stream * @param options */ function Peer(config) { var _this = _super.call(this, config) || this; _this.initPeerConnection(config.stream, config.iceConfig); return _this; } Peer.prototype.initPeerConnection = function (stream, iceConfig) { var self = this; self.channels = {}; self.pcEvent = new EventEmitter(); var iceServers; if (!!iceConfig) iceServers = iceConfig; else iceServers = this.configuration; this.pc = new RTCPeerConnection(iceServers); if (self.debug) { console.log(JSON.stringify(iceServers)); console.log("connection: " + this.pc.iceConnectionState + ", Gathering: " + this.pc.iceGatheringState + ", signaling: " + this.pc.signalingState); } this.pc.onnegotiationneeded = function () { if (self.debug) console.log("onnegotiationneeded"); self.pcEvent.emit(AbstractPeerConnection.PeerEvent, "onnegotiationneeded"); if (self.offer) { self.createOffer(); } }; this.pc.onicecandidate = function (event) { self.send_event(AbstractPeerConnection.CANDIDATE, event.candidate, { to: self.id }); }; this.pc.oniceconnectionstatechange = function (event) { var target = event.target; if (self.debug) console.log('oniceconnectionstatechange', target.iceConnectionState); self.pcEvent.emit("oniceconnectionstatechange", target.iceConnectionState); if (target.iceConnectionState === 'completed') { // setTimeout(() => { // self.getStats(); // }, 1000); self.parentsEmitter.emit(AbstractPeerConnection.ON_ICE_COMPLETED, self.pcPeers); } if (target.iceConnectionState === 'connected') { self.createDataChannel(); self.parentsEmitter.emit(AbstractPeerConnection.ON_ICE_CONNECTED, self.pcPeers); } else if (target.iceConnectionState == "failed") { self.parentsEmitter.emit(AbstractPeerConnection.ON_ICE_CONNECTION_FAILED, self.pcPeers); self.send_event(AbstractPeerConnection.CONNECTIVITY_ERROR, null, { to: self.id }); } else if (target.iceConnectionState == "closed") { self.parentsEmitter.emit(AbstractPeerConnection.ON_ICE_CONNECTION_CLOSED, self.pcPeers); } }; this.pc.onicegatheringstatechange = function (event) { var target = event.target; if (self.debug) console.log("onicegatheringstatechange", target.iceGatheringState); // When iceGatheringState == complete it fire onicecandidate with null. if (target.iceGatheringState == "complete") { self.sendOffer(); } self.pcEvent.emit("onicegatheringstatechange", target.iceGatheringState); }; this.pc.onsignalingstatechange = function (event) { var target = event.target; if (self.debug) console.log('onsignalingstatechange', target.signalingState); self.pcEvent.emit("onsignalingstatechange", target.signalingState); }; this.pc.onaddstream = function (peer) { if (self.debug) console.log('onaddstream'); self.parentsEmitter.emit(AbstractPeerConnection.PEER_STREAM_ADDED, peer); }; this.pc.onremovestream = function (peer) { if (self.debug) console.log('onremovestream'); self.parentsEmitter.emit(AbstractPeerConnection.PEER_STREAM_REMOVED, peer.stream); }; this.pc.addStream(stream); self.parentsEmitter.emit(AbstractPeerConnection.CREATED_PEER, self); }; Peer.prototype.getStats = function () { var self = this; var peer = this.pcPeers[Object.keys(this.pcPeers)[0]]; var pc = peer.pc; if (pc.getRemoteStreams()[0] && pc.getRemoteStreams()[0].getAudioTracks()[0]) { var track = pc.getRemoteStreams()[0].getAudioTracks()[0]; console.log('track', track); pc.getStats(track, function (report) { console.log('getStats report', report); }, self.logError); } }; Peer.prototype.handleMessage = function (message) { var self = this; if (self.debug) console.log('handleMessage', message.type); if (message.prefix) this.browserPrefix = message.prefix; if (message.type === AbstractPeerConnection.OFFER) { if (!this.nick) this.nick = message.payload.nick; delete message.payload.nick; // Not support promise return type. self.pc.setRemoteDescription(new RTCSessionDescription(message.payload), function success() { if (self.debug) console.log("setRemoteDescription complete"); if (self.pc.remoteDescription.type == AbstractPeerConnection.OFFER) { self.createAnswer(message); } }, self.onSetSessionDescriptionError); } else if (message.type === AbstractPeerConnection.ANSWER) { // Not support promise return type. self.pc.setRemoteDescription(new RTCSessionDescription(message.payload), function () { if (self.debug) console.log("setRemoteDescription complete"); }, self.onSetSessionDescriptionError); } else if (message.type === AbstractPeerConnection.CANDIDATE) { if (!message.payload) return; self.pc.addIceCandidate(new RTCIceCandidate(message.payload)); } else if (message.type === AbstractPeerConnection.CONNECTIVITY_ERROR) { this.parentsEmitter.emit(AbstractPeerConnection.CONNECTIVITY_ERROR, self.pc); } }; ; Peer.prototype.createDataChannel = function () { if (this.pc.textDataChannel) { return; } var dataChannel = this.pc.createDataChannel("text"); dataChannel.onerror = function (error) { console.log("dataChannel.onerror", error); }; dataChannel.onmessage = function (event) { console.log("dataChannel.onmessage:", event.data); var message = event.data; if (message.type === 'connectivityError') { this.parentsEmitter.emit(AbstractPeerConnection.CONNECTIVITY_ERROR, self); } else if (message.type === 'endOfCandidates') { // Edge requires an end-of-candidates. Since only Edge will have mLines or tracks on the // shim this will only be called in Edge. var mLines = this.pc.pc.transceivers || []; mLines.forEach(function (mLine) { if (mLine.iceTransport) { mLine.iceTransport.addRemoteCandidate({}); } }); } }; dataChannel.onopen = function () { console.log('dataChannel.onopen'); }; dataChannel.onclose = function () { console.log("dataChannel.onclose"); }; this.pc.textDataChannel = dataChannel; }; return Peer; }(AbstractPeer.BasePeer)); export { Peer };