UNPKG

cione-comp-lib

Version:

`$ yarn add cione-comp-lib` 或者 `$ npm i cione-comp-lib -S`

197 lines (196 loc) 6.24 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => { __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class WebRTC { constructor(host, port) { __publicField(this, "host"); __publicField(this, "port"); __publicField(this, "userId"); __publicField(this, "isReady"); __publicField(this, "messageList"); __publicField(this, "icecandidateList"); __publicField(this, "handlerMap"); __publicField(this, "socket"); __publicField(this, "peer"); this.host = host; this.port = port; this.userId = 0; this.isReady = false; this.messageList = []; this.icecandidateList = []; this.handlerMap = {}; this.socket = null; this.peer = null; this.init(); } static checkSupport() { const RTCPeer = RTCPeerConnection || webkitRTCPeerConnection || mozRTCPeerConnection; return !!RTCPeer; } static createPeer() { const RTCPeer = RTCPeerConnection || webkitRTCPeerConnection || mozRTCPeerConnection; const config = { iceServers: [{ urls: ["stun:stun.xten.com", "stun:stun.l.google.com:19302"] }] }; return new RTCPeer(config); } static createIceCan(data) { const RTCIce = RTCIceCandidate || webkitRTCIceCandidate || mozRTCIceCandidate; return new RTCIce(data); } static createDescript(data) { const RTCDesc = RTCSessionDescription || webkitRTCSessionDescription || mozRTCSessionDescription; return new RTCDesc(data); } init() { const connectionStr = `wss://${this.host}${this.port ? `:${this.port}` : ""}/webrtc?password=123`; const socket = new WebSocket(connectionStr); this.socket = socket; socket.onopen = this.onOpen.bind(this); socket.onmessage = this.onMessage.bind(this); socket.onclose = this.onClose.bind(this); socket.onerror = this.onError.bind(this); } initPeer(msg) { const peer = WebRTC.createPeer(); this.peer = peer; this.initPeerBind(msg); } initPeerBind(msg) { const peer = this.peer; peer.onconnectionstatechange = this.onPeerConnectionChange.bind(this, msg); peer.onicecandidate = this.onPeerIceCandidate.bind(this, msg); peer.ontrack = this.onPeerAddTrack.bind(this, msg); } onPeerConnectionChange(msg, event) { this.debug("peer connection change", this.peer.connectionState); let status = 0; if (this.peer.connectionState === "connecting") status = 1; if (this.peer.connectionState === "connected") { status = 2; this.excuteHandler("connected", {}); } if (this.peer.connectionState === "disconnected") { status = 0; this.excuteHandler("disconnected", {}); } this.send({ event: "status", userId: this.userId, data: { hasConnection: status } }); } onPeerAddTrack(msg, event) { this.excuteHandler("track", event); } onPeerIceCandidate(msg, event) { if (event.candidate && event.candidate.protocol == "udp") { const data = event.candidate; const sendMsg = { event: "ice", userId: this.userId, toUserId: msg.fromUserId, data }; this.send(sendMsg); } } onOpen() { this.isReady = true; } onMessage(event) { const { data } = event; const msg = typeof data === "string" ? JSON.parse(data) : data; const handler = this[msg.event]; if (msg.status === 500) return this.debug("fail", msg.msg); if (msg.event === "connection") { this.userId = Number(msg.userId) || 0; this.send({ event: "info", userId: this.userId, data: { userName: "SDA", desc: "SDA\u7EC4\u4EF6", type: "window", canP2P: false } }); this.excuteHandler("connection", {}); return; } if (!handler) return this.debug("fail", "\u5904\u7406\u51FD\u6570\u4E0D\u5B58\u5728"); handler.call(this, msg); } onClose() { this.isReady = false; } onError(error) { this.debug("error", error); } publisher(msg) { const { userId, toUserId } = msg; const sendMsg = { event: "subscriber", userId: this.userId, toUserId }; if (this.peer) { this.peer.close(); this.peer = null; } this.initPeer({ userId, fromUserId: toUserId }); this.send(sendMsg); } async offer(msg) { const { data, toUserId } = msg; const desc = WebRTC.createDescript(data); let ans; let ice; if (!desc) return; try { await this.peer.setRemoteDescription(desc); ans = await this.peer.createAnswer(); await this.peer.setLocalDescription(ans); this.send({ event: "answer", userId: this.userId, toUserId, data: this.peer.localDescription }); ice = this.icecandidateList.shift(); while (ice) { const iceItem = WebRTC.createIceCan(ice); this.peer.addIceCandidate(iceItem); ice = this.icecandidateList.shift(); } } catch (error) { this.debug("offer", error); } } ice(msg) { const { data } = msg; if (this.peer.remoteDescription) { const ice = WebRTC.createIceCan(data); this.peer.addIceCandidate(ice); } else { this.icecandidateList.push(data); } } excuteHandler(event, data) { const handlerList = this.handlerMap[event]; if (!handlerList) return; for (let i = 0; i < handlerList.length; i++) { const func = handlerList[i]; func(data); } } debug(key, data) { console.log(`============>:${key}`); console.log(data); } send(data) { const msg = JSON.stringify(data); if (!this.isReady) return this.messageList.push(msg); this.socket.send(msg); } on(event, func) { const handlerList = this.handlerMap[event]; if (!handlerList) this.handlerMap[event] = []; this.handlerMap[event].push(func); } off(event, func) { const handlerList = this.handlerMap[event]; let index; if (!handlerList) return; index = handlerList.findIndex((it) => it == func); if (index >= 0) handlerList.splice(index, 1); if (!handlerList.length) delete this.handlerMap[event]; } } export { WebRTC as default };