WebRTC Firefox <=> Chrome:Chrome关闭连接,而不关闭Firefox

时间:2019-02-19 13:47:53

标签: webrtc

我有一个简单的WebRTC应用程序,仅传输文本数据。除了处理睡眠模式外,它都很好用。

例如,我在计算机的两个不同选项卡上与两个用户进行本地测试,然后将计算机(macOS)置于睡眠模式。不同的情况:

  • Chrome上的两个用户:进入睡眠模式时,rtc连接立即在两侧断开,易于处理和恢复,确定
  • 同时使用Firefox的用户:如果计算机很快唤醒,则rtc连接不会断开,或者如果睡眠足够长,则双向断开;易于处理和恢复,确定
  • Chrome上的一个用户和Firefox上的一个:进入睡眠模式时,Chrome用户会立即断开连接(触发了dataChannel onclose),但是Firefox用户却没有,并且仍然认为dataChannel正在正常工作(使用send不会触发错误,但是很明显,Chrome上的用户因为旁边已经关闭而没有收到消息),问题

为什么onclose事件在另一侧触发时却没有在Firefox侧触发?

是否有替代解决方案来查找连接是否断开?

如果有帮助,我的代码的一部分:

const configuration = {
  iceServers: [
    {urls: 'stun:stun.l.google.com:19302'},
    {urls: 'turn:numb.viagenie.ca', username: '...', credential: '...'},
  ]
}


// Keep track of all RTCPeerConnection.
// Key is userId aka peerId, value is object with 'conn' and 'dataChannel' keys.
let peers = {}


const onNewPeer = (peerId, username) => {
  if (peerId in peers) {
    log('Already connected to peer ' + peerId)
    return
  }

  const peerconn = new RTCPeerConnection(configuration)

  // 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
  // message to the other peer through the signaling server
  peerconn.onicecandidate = event => {
    if (event.candidate)
      sendSignalingMessage({ candidate: event.candidate, toUserId: peerId })
  }

  // OFFERER SPECIFIC PART
  peerconn.onnegotiationneeded = () => {
    peerconn.createOffer().then(desc => setLocalDescription(desc, peerId), error => console.error(error))
  }

  const dataChannel = peerconn.createDataChannel('chat')  // RTCDataChannel
  setupDataChannel(dataChannel, peerId, username)

  sendSignalingMessage({ type: 'ADD_PEER_ANSWER', toUserId: peerId })
  // END OFFERER SPECIFIC

  peers[peerId] = { conn: peerconn, username: username, dataChannel: dataChannel }
}


const onNewPeerAnswer = (peerId, username) => {
  if (peerId in peers) {
    log('Already connected to peer ', peerId)
    return
  }

  const peerconn = new RTCPeerConnection(configuration)

  // 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
  // message to the other peer through the signaling server
  peerconn.onicecandidate = event => {
    if (event.candidate)
      sendSignalingMessage({ candidate: event.candidate, toUserId: peerId })
  }

  // ANSWERER SPECIFIC PART
  // If user is not the offerer, let's wait for a data channel
  peerconn.ondatachannel = event => {
    const dataChannel = event.channel  // RTCDataChannel
    setupDataChannel(dataChannel, peerId, username)
    peers[peerId]['dataChannel'] = dataChannel
  }
  // END ANSWERER SPECIFIC

  peers[peerId] = { conn: peerconn, username: username }
}


const setupDataChannel = (dataChannel, peerId, username) => {
  dataChannel.onopen = () => {
    console.log(`%cYou are now connected to ${peerId} aka ${username}`, 'color: green;')
  }

  // PROBLEM: this is triggered on Chrome when going to sleep,
  // but on firefox side this is not triggered and firefox still
  // thinks this dataChannel is opened after waking up.
  dataChannel.onclose = () => {
    delete peers[peerId]
    console.log(`%cDisconnected from ${peerId} aka ${username}`, 'color: red;')
  }

  dataChannel.onerror = () => {
    delete peers[peerId]
    console.log(`%cDisconnected from ${peerId} aka ${username} (onerror)`, 'color: red;')
  }

  dataChannel.onmessage = event => {
    log('Received through WebRTC: ', JSON.parse(event.data))
  }
}

0 个答案:

没有答案