Websocked mainly realizes message communication such as text message, binary image recording

WebRtc mainly realizes the communication of video and audio stream

GetUserMedia mainly achieves the acquisition of the browser camera microphone and video and audio streams

The first step is to create a webScoked object, and use webSocked events to monitor the working status of webSocked. In the onopen event, the webSocked connection is successfully detected, and the send method is used to send messages where needed. You can listen for communication messages in the onMessage event and process them, and onClose is called when unexpected errors occur or webSocked needs to be turned off

Part of the code the init () {if (this. Brid) {let url = window. Config. BaseConfig. SocketUrl + enclosing brid enclosing webSock = new WebSocket(url) this.webSock.onopen = this.webSockOpen this.webSock.onerror = this.webSocketError this.webSock.onmessage = this.websocketmsg this.websocket.onclose = this.websocketClose}}, webSockOpen() {console.log(' Connection succeeded! ') }, webSocketMsg(evt) { try { let data = JSON.parse(evt.data), id = data.id, i = this.tempMsg[id] if (data.code === 1) { this.msgs[i].code = 1 } else if (data.code === 2 && ! i) { this.tempMsg[id] = true this.msgs.push(data) this.webSock.send(JSON.stringify({code: '3', id: Id}))}} Catch (e) {}}, webSocketError(e) {console.error(e)}, webSocketClose() {console.warn(' close webSock')}, send(val) { let id = this.brid + new Date().getTime(), data = { code: '0', id: id, from: this.brid, to: this.to, msg: this.value || val } this.webSock.send(JSON.stringify(data)) this.$refs.input.innerHTML = '' this.value = '' this.tempMsg[id] = this.msgs.length this.msgs.push(data) }Copy the code

Next, get the browser camera, microphone, and data stream. Note browser compatibility

navigator.mediaDevices.getUserMedia({
    //constraints
    video: true,
    audio: true
}).then(stream => {
    const video = document.querySelector('video');
    video.srcObject = stream;
}).catch(error => {
    alert('error: ', error)
})
Copy the code

The constraints object we can use to specify some properties related to media streaming. For example, you can specify whether to get a certain stream, the width and height of the video stream, the frame rate and the desired value, and for mobile devices, you can also specify whether to get the front camera or the rear camera.

Finally, the three are combined to realize a data flow communication, and the general communication process is as follows:

1. The sender starts the local video (get the browser camera and microphone), adds it to the channel, and sends the video invitation {event: ‘invite’, to: ‘receiver ID ‘, type: ‘1’}

2. If the sender cancels the call before the receiver, it shall notify the other party of the cancellation {event: ‘cancle’, to: ‘receiver ID ‘, type: ‘1’}

3. If the receiver hangs up the phone, notify the receiver that the phone has hung up {event: ‘close’, to: ‘receiver ID ‘, type: ‘1’}

4. If the receiver answers the call, the local video needs to be started and added to the channel (to obtain the browser camera and microphone), the initiator needs to reply {event: ‘reply’, to: ‘receiver ID ‘, type: ‘1’}

5. After receiving the reply, the initiator sends the iceCandidate and officeSdp

AddIceCandidate (new RTCIceCandidate(json.parse (data.msg))) SetRemoteDescription (new RTCSessionDescription(json.parse (data.msg))), then answerSdp on the reply initiator

7, the initiator receives answerSdp, execute setRemoteDescription(new RTCSessionDescription(json.parse (data.msg))

Partial implementation code

creatRTCPreeConnection() { // let iceServer = {iceServer: {'iceServers': [{'url': 'turn:172.16.113.146:3478', 'username': 'daiyao', 'credential': 'daiyao'}]}} let iceServer = {'iceServers': [{'url': 'stun:stun.voiparound.com'}]} this.cn = new RTCPeerConnection(iceServer) console.log(this.cn) this.cn.onaddstream = (event) => { if (this.isVideo) { document.getElementById('remoteVideo').srcObject = event.stream } else { document.getElementById('remoteAudio').srcObject = event.stream } } }, video() { this.showTh = true let thObj = { event: 'invite', to: '2815718', // to: '4223', type: '1', tips: 'Send video invite'} this.sendth(thObj)}, sendth(val) {console.log(val) this.websock. Send (json.stringify (val))}, dealVideoMsg(data) { if (data.event === 'invite') { this.isShow.invite = data.event this.showTh = true if (data.kind ===  'audio') { this.isShow.media = 'video' this.isVideo = false } if (this.isOpen) { this.creatRTCPreeConnection() this.GetUserMedia(data.from, false) let thObj = { type: '1', event: 'reply', to: data.from, tips: 'Received' + data.from + 'video invitation, Invite = null this.isshow. all = 'all'}} else if (data.event === 'reply') {} this.sendth(thObj) this.isshow. invite = null this.isshow. all = 'all'}} else if (data.event === 'reply') { this.isShow.reply = data.event this.creatRTCPreeConnection() this.sendCandidate(data.from) this.GetUserMedia(data.from, true) } else if (data.event === 'candidate') { this.cn.addIceCandidate(new RTCIceCandidate(JSON.parse(data.msg))) } else  if (data.event === 'offerSdp') { this.cn.setRemoteDescription(new RTCSessionDescription(JSON.parse(data.msg))) this.createAnswer(data.from) } else if (data.event === 'answerSdp') { this.cn.setRemoteDescription(new RTCSessionDescription(JSON.parse(data.msg))) } }, GetUserMedia(toUserId, isCaller) { navigator.webkitGetUserMedia({'audio': this.isAudio, 'video': this.isVideo}, (stream) => { console.log(this.isVideo) if (this.isVideo) { console.log(this.isVideo) document.getElementById('localVideo').srcObject = stream } else { document.getElementById('localAudio').srcObject = stream } this.cn.addStream(stream) if (isCaller) { this.creatOf(toUserId) } }, (error) => { console.log('getUserMedia error: ' + error) } ) }, sendCandidate(toUserId) { console.log(this.cn) console.log(this.cn.onicecandidate) this.cn.onicecandidate = (event) => {  console.log(event.candidate) if (event.candidate ! == null) { var thObj = { type: '1', event: 'candidate', msg: event.candidate, to: toUserId, tips: Sendth (thObj)}}, creatOf(toUserId) { this.cn.createOffer((offerSdp) => { console.log('1') this.cn.setLocalDescription(offerSdp) var thObj  = { type: '1', msg: offerSdp, event: 'offerSdp', to: toUserId, tips: 'offerSdp' } console.log('111') this.sendth(thObj) }, (error) => { console.log('Failure callback:' + error) }) }, createAnswer(toUserId) { this.cn.createAnswer((answerSdp) => { this.cn.setLocalDescription(answerSdp) var thObj = { type: '1', msg: answerSdp, event: 'answerSdp', to: toUserId, tips: 'answerSdp' } this.sendth(thObj) }, (error) => { console.log('Failure callback:' + error) }) }Copy the code