在react.js和meteor.js上出现简单的WebRTC聊天错误

时间:2017-02-25 13:58:59

标签: javascript node.js reactjs meteor webrtc

我尝试使用webrtc技术react.jsmeteor.js进行简单的聊天。 这是客户端代码:

 class Rtc extends Component {
   constructor(props) {
     super(props);
   }

   componentDidUpdate(){
     let localVideo, remoteVideo, peerConnection, localStream;
     $('#start').on('click', ()=>{ start(true) });
     let id = Meteor.uuid();
     localVideo = document.getElementById('localVideo');
     remoteVideo = document.getElementById('remoteVideo');

     if (!this.props.loadingRtc) {
       this.props.messagesRtc.forEach((item, i ,arr)=>{
         let signal = JSON.parse(item.text);
         if(i == 0)return;
         gotMessageFromServer(signal);
       });
     }

     if(navigator.mediaDevices.getUserMedia) {
       navigator.mediaDevices.getUserMedia( { video:true, audio:true}).then( ( stream )=> {
         localStream = stream;
         localVideo.src = window.URL.createObjectURL(stream);
       }).catch(errorHandler);
     } else { alert('Your browser does not support getUserMedia API'); }

     function start(isCaller) {
       peerConnection = new RTCPeerConnection( { 'iceServers': [{'urls': 'stun:stun.services.mozilla.com'}, {'urls': 'stun:stun.l.google.com:19302'},]});
       peerConnection.onicecandidate = ( e ) => {
         console.log('e.candidate', e.candidate);
         if(e.candidate != null) {
           Meteor.call('addMsgRtc', JSON.stringify({'ice': e.candidate, '_id':id}), id);
         }
       };

       peerConnection.onaddstream = ( e )=>{
         remoteVideo.src = window.URL.createObjectURL(e.stream);
       };
       peerConnection.addStream(localStream);
       if(isCaller) {
         peerConnection.createOffer().then(createdDescription).catch(errorHandler);
       }
     }

     function gotMessageFromServer(signal) {
       if(!peerConnection)  start(false);      
       if(signal._id == id) return;
       if(signal.sdp) {
         peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp)).then(()=> {
           if(signal.sdp.type == 'offer') {
             peerConnection.createAnswer().then(createdDescription).catch(errorHandler);
           }
         }).catch(errorHandler);
       } else if(signal.ice) {
         peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(errorHandler);
       }
     }
     function createdDescription(description) {
       peerConnection.setLocalDescription(description).then(()=> {
         Meteor.call('addMsgRtc', JSON.stringify({'sdp':peerConnection.localDescription, '_id':id}), id);
       }).catch(errorHandler);
     }
     function errorHandler(error) { console.log(error); }
   }

   render() {
     return (
       <div>
         <video id="localVideo"  autoPlay muted style={{width:"40%"}}></video>
         <video id="remoteVideo" autoPlay       style={{width:"40%"}}></video>
         <br/>
         <input type="button" id="start" value="Start Video"/>
       </div>
     );
   }
 }


 export default createContainer( ()=> {
   const subscriptionRtc = Meteor.subscribe('rtc');
   const loadingRtc = !subscriptionRtc.ready();
   return {
     loadingRtc:loadingRtc,
     messagesRtc: msgRtc.find().fetch(),
   };
 }, App);

服务器代码:

export const msgRtc = new Mongo.Collection('rtc');
 let messagesRtc = [];
 let clients = [];

  Meteor.publish('rtc', function wsPub() {
    clients.push(this);
    _.each(messagesRtc, (message) => {
      this.added('rtc', message._id, message);
    });
    this.ready();
  });

 Meteor.methods({
    'addMsgRtc'(arr, id) {
      let newMessage = {_id:id, 'text':arr};
      messagesRtc.push(newMessage);
      _.each(clients, (client) => {
        client.added('rtc', id, newMessage);      
      });
    },

问题在于,为什么在getUserMedia初始化之后不希望进一步推广这些视频,哪些不是我无法理解的。因为它实际上是与通常的websockets like this相似的代码,并且同步很好。

UPD:
单击按钮并调用函数start时。

  

TypeError:RTCPeerConnection.addStream的参数1不是对象

如果要放入websockets,则会发现另一个错误:

代码:

 navigator.mediaDevices.getUserMedia( { video:true, audio:true}).then( ( stream )=> {
    localStream = stream;
    localVideo.src = window.URL.createObjectURL(stream);
  }).catch(errorHandler).then(()=>{
    if (!this.props.loadingRtc) {
      for(let i of this.props.messagesRtc){
        let signal = JSON.parse(i.text);
        gotMessageFromServer(signal)
      }
    }
  }).catch(errorHandler);

错误:

  

DOMException [InvalidStateError:&#34;无法设置远程报价或答案   目前的州有远程提供&#34;代码:11 nsresult:0x8053000b]   app.js:11075:9 DOMException [InvalidStateError:&#34;没有未完成的优惠&#34;   代码:11 nsresult:0x8053000b]

0 个答案:

没有答案