现有主流浏览器基本上都已经支持webrtc,可以基于js实现非常简洁的webrtc连接建立,我么采用了mqtt协议进行信令传输,方便设备管理。采用了开源emqx作为mqtt服务器,架构非常简介高效,可以很好的融合到各种iot物联网系统架构中,可以先建立mqtt连接,相应的设备采用消息订阅的方式等待相关控制指令

  当mqtt连接建立后,就可以通过RTCpeerconnect 建立webrtc通道创建本地offer,并向需要远程控制的设备ID发布SDP offer,并等待设备的answer,当收到answer时则设置remoteDescription,同时可以收到webrtc的ontrake事件,基于webrtc的音视频通道即可建立,同时createDataChannel实现数据通道的点对点通道,还通过mqtt协议实现心跳数据以及其他相关指令交互。

以下代码为相关核心代码,是不是非常简单就实现了webrtc的通道建立,你只需要搭建一个简单的ICEserver 实现 NAT coturn或者go语言实现turn服务也很方便,一个可无鲜限拓展的远程维护云平台即搭建完成。

function initMqtt(){

   var ClientId = 'mqttjs_' + Math.random().toString(16).substr(2, 8)
    mqttclient  = mqtt.connect(MqttServer,
    {
		clientId: ClientId,
		username: 'admin',
		password: 'password'
	});
    mqttclient.on('connect', function () {
       mqttclient.subscribe(subtopic, function (err) {
        if (!err) {
            //mqttclient.publish('Control', 'Hello mqtt')
        //成功连接到服务器
        console.log("connected to server");
        initWebRTC();
        }
       })
   })

    mqttclient.on('message', function (topic, message) {
  // message is Buffer
      console.log(topic)
      console.log(message)
    
    let input=JSON.parse(message)
    console.log(input)

    switch(input.type){
	case "error":
	   console.log(input.msg);
       stopSession();
	   break;
    case "answer":
       var remoteSessionDescription = input.data;
       if (remoteSessionDescription === '') {
        alert('Session Description must not be empty');
       }
       try {
        let answer=JSON.parse(atob(remoteSessionDescription))
        console.log(answer)
        pc.setRemoteDescription(new RTCSessionDescription(answer));
        btnOpen();
       } catch (e) {
        alert(e);
       }
	   break;
    case CMDMSG_DISCRSP:
	   console.log(JSON.parse(atob(input.data)));
	   getDevices(JSON.parse(atob(input.data)))
	   break;
	case "heart":
	    console.log(JSON.parse(atob(input.data)));
		break;
	case "cmdFeedback":	
	    console.log(JSON.parse(atob(input.data)));
		break;
	case CMDMSG_PROCLIST:	
	    console.log(JSON.parse(atob(input.data)));
		break;
    case CMDMSG_RESPKVMRTSPINFOLIST:
        console.log(JSON.parse(atob(input.data)));
		break;
		}
	})   
}
function initWebRTC(){
    if (bWebrtc==true) return
    bWebrtc=true
    pc = new RTCPeerConnection({
        iceServers: ICEServers//ICEServer

    });
    pc.addTransceiver('video')
    pc.ontrack = function (event) {
        console.log("ontrack")
 
           trackCache = event.track;
           var el = document.getElementById('remote-video')
            resStream = event.streams[0].clone()
            resStream.addTrack(trackCache)
            el.srcObject = resStream
            KeyMouseCtrl()

    }

    initSSH();
    initControl();
    //initSerial();
    pc.oniceconnectionstatechange = e => log(pc.iceConnectionState)
  
   
    pc.onicecandidate = event => {
        if (event.candidate === null) {
            var msgdata = new Object();
           
            msgdata["seqid"]=2;
            msgdata["video"]=true
            msgdata["serial"]=true
            msgdata["ssh"]=true

            msgdata["iceserver"]=ICEServerkvm;
            msgdata["offer"]=pc.localDescription//localSessionDescription;
            msgdata["rtspaddr"]=KVMRTSPADDR
            msgdata["suuid"]=kvmstream

               
            var content = new Object();
            content["type"]=CMDMSG_OFFER;
            content["msg"]="webrtc offer";
            content["device_id"]=deviceID;
            content["data"]=btoa(JSON.stringify(msgdata));
            mqttclient.publish(pubtopic, JSON.stringify(content));
   

            console.log("localDescription:",btoa(JSON.stringify(pc.localDescription)));
        }
    }


    pc.createOffer().then(d => pc.setLocalDescription(d)).catch(log)
}

function initControlHID(){
    controlHID = pc.createDataChannel("HID");
    //HidMap()
}

 

 

Logo

开源、云原生的融合云平台

更多推荐