import AbstractConnection from "./Connection.js" import LioWebRTC from "liowebrtc" export default class WebRTCConnection extends AbstractConnection { constructor(options) { super(options) this.webrtc = new LioWebRTC({ url: this.options.url, dataOnly: true, constraints: { minPeers: this.options.mesh.minPeers, maxPeers: this.options.mesh.maxPeers, }, }) this.webrtc.on("ready", () => { this.webrtc.joinRoom(this.options.room) }) this.webrtc.on("joinedRoom", () => { this.dispatchEvent(new CustomEvent("roomJoined")) }) this.webrtc.on("leftRoom", () => { this.dispatchEvent(new CustomEvent("roomLeft")) }) this.webrtc.on("channelOpen", (dataChannel, peer) => { this.dispatchEvent(new CustomEvent("channelOpened", { detail: peer.id })) }) this.webrtc.on("channelError", (dataChannel, peer) => { this.dispatchEvent(new CustomEvent("channelError", { detail: peer.id })) }) this.webrtc.on("channelClose", (dataChannel, peer) => { this.dispatchEvent(new CustomEvent("channelClosed", { detail: peer.id })) }) this.webrtc.on("receivedPeerData", (channel, message, peer) => { // Message could have been forwarded but interface only needs to know about directly connected peers this.dispatchEvent( new CustomEvent("messageReceived", { detail: { uid: peer.forwardedBy ? peer.forwardedBy.id : peer.id, channel, message, }, }), ) }) } getUserID() { return this.webrtc.getMyId() } getPeerHandle(uid) { return this.webrtc.getPeerById(uid) } getPeerFootprint(uid) { const peer = this.webrtc.getPeerById(uid) if (!peer) return Promise.reject() return new Promise(function(resolve, reject) { peer.getStats(null).then((stats) => { let footprint = -1 stats.forEach((report) => { if ( report.type == "candidate-pair" && report.bytesSent > 0 && report.bytesReceived > 0 && report.writable ) { footprint = Math.max(footprint, report.bytesReceived) } }) if (footprint != -1) { resolve(footprint) } else { reject() } }) }) } send(uid, channel, message) { const peer = this.webrtc.getPeerById(uid) if (!peer) return this.webrtc.whisper(peer, channel, message) } broadcast(channel, message) { this.webrtc.shout(channel, message) } terminatePeer(uid) { const peer = this.webrtc.getPeerById(uid) if (!peer) return peer.end() } destructor() { this.webrtc.quit() } }