Merge pull request #4182 from nextcloud/stop-sending-the-nick-through-data-channels-after-some-time

Stop sending the nick through data channels after some time
This commit is contained in:
Vincent Petry 2020-11-19 13:21:01 +01:00 коммит произвёл GitHub
Родитель 3f0f8efaae 259cb4e0a0
Коммит 6b7db03096
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 81 добавлений и 72 удалений

Просмотреть файл

@ -170,11 +170,11 @@ CallParticipantModel.prototype = {
},
_handleNick: function(data) {
if (!this.get('peer') || this.get('peer').id !== data.id) {
// The nick could be changed even if there is no Peer object.
if (this.get('peerId') !== data.id) {
return
}
this.set('userId', data.userid || null)
this.set('name', data.name || null)
},

Просмотреть файл

@ -125,7 +125,7 @@ LocalCallParticipantModel.prototype = {
this.set('guestName', guestName)
this._webRtc.sendDirectlyToAll('status', 'nickChanged', guestName)
this._webRtc.webrtc.emit('nickChanged', guestName)
},
_handleForcedMute: function() {

Просмотреть файл

@ -119,6 +119,10 @@ function SimpleWebRTC(opts) {
self.emit('mute', { id: message.payload.peerId })
}
}
} else if (message.type === 'nickChanged') {
// "nickChanged" can be received from a participant without a Peer
// object if that participant is not sending audio nor video.
self.emit('nick', { id: message.from, name: message.payload.name })
} else if (peers.length) {
peers.forEach(function(peer) {
if (message.sid && !self.connection.hasFeature('mcu')) {

Просмотреть файл

@ -47,7 +47,7 @@ const delayedConnectionToPeer = []
let callParticipantCollection = null
let localCallParticipantModel = null
let showedTURNWarning = false
let sendCurrentMediaStateWithRepetitionTimeout = null
let sendCurrentStateWithRepetitionTimeout = null
function arrayDiff(a, b) {
return a.filter(function(i) {
@ -159,15 +159,23 @@ function sendCurrentMediaState() {
}
}
function sendCurrentMediaStateWithRepetition(timeout) {
// TODO The participant name should be got from the participant list, but it is
// not currently possible to associate a Nextcloud ID with a standalone
// signaling ID for guests.
function sendCurrentNick() {
webrtc.webrtc.emit('nickChanged', store.getters.getDisplayName())
}
function sendCurrentStateWithRepetition(timeout) {
if (!timeout) {
timeout = 0
clearTimeout(sendCurrentMediaStateWithRepetitionTimeout)
clearTimeout(sendCurrentStateWithRepetitionTimeout)
}
sendCurrentMediaStateWithRepetitionTimeout = setTimeout(function() {
sendCurrentStateWithRepetitionTimeout = setTimeout(function() {
sendCurrentMediaState()
sendCurrentNick()
if (!timeout) {
timeout = 1000
@ -176,11 +184,11 @@ function sendCurrentMediaStateWithRepetition(timeout) {
}
if (timeout > 16000) {
sendCurrentMediaStateWithRepetitionTimeout = null
sendCurrentStateWithRepetitionTimeout = null
return
}
sendCurrentMediaStateWithRepetition(timeout)
sendCurrentStateWithRepetition(timeout)
}, timeout)
}
@ -238,15 +246,17 @@ function usersChanged(signaling, newUsers, disconnectedSessionIds) {
|| (!signaling.hasFeature('mcu') && user && !userHasStreams(user) && !webrtc.webrtc.localStreams.length)) {
callParticipantModel.setPeer(null)
// As there is no Peer for the other participant the current media
// state will not be sent once it is connected, so it needs to be
// sent now.
// When there is no MCU this is not needed; as the local participant
// has no streams it will be automatically marked with audio and
// video not available on the other end, so there is no need to send
// the media state.
// As there is no Peer for the other participant the current state
// will not be sent once it is connected, so it needs to be sent
// now.
// When there is no MCU this is only needed for the nick; as the
// local participant has no streams it will be automatically marked
// with audio and video not available on the other end, so there is
// no need to send the media state.
if (signaling.hasFeature('mcu')) {
sendCurrentMediaStateWithRepetition()
sendCurrentStateWithRepetition()
} else {
sendCurrentNick()
}
}
@ -499,56 +509,14 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
webrtc.sendDirectlyToAll(channel, message, payload)
}
// The nick name below the avatar is distributed through the DataChannel
// of the PeerConnection and only sent once during establishment. For
// the MCU case, the sending PeerConnection is created once and then
// never changed when more participants join. For this, we periodically
// send the nick to all other participants through the sending
// PeerConnection.
//
// TODO: The name for the avatar should come from the participant list
// which already has all information and get rid of using the
// DataChannel for this.
function stopSendingNick(peer) {
if (!peer.nickInterval) {
return
}
clearInterval(peer.nickInterval)
peer.nickInterval = null
}
function startSendingNick(peer) {
if (!signaling.hasFeature('mcu')) {
return
}
stopSendingNick(peer)
peer.nickInterval = setInterval(function() {
let payload
if (signaling.settings.userId === null) {
payload = store.getters.getDisplayName()
} else {
payload = {
'name': store.getters.getDisplayName(),
'userid': signaling.settings.userId,
}
}
peer.sendDirectly('status', 'nickChanged', payload)
}, 1000)
}
function handleIceConnectionStateConnected(peer) {
// Send the current information about the video and microphone
// state.
// Send the current information about the state.
if (!signaling.hasFeature('mcu')) {
// Only the media state needs to be sent, the nick was already sent
// in the offer/answer.
sendCurrentMediaState()
} else {
sendCurrentMediaStateWithRepetition()
}
if (signaling.settings.userId === null) {
const currentGuestNick = store.getters.getDisplayName()
sendDataChannelToAll('status', 'nickChanged', currentGuestNick)
sendCurrentStateWithRepetition()
}
// Reset ice restart counter for peer
@ -716,8 +684,6 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
if (peer.type === 'video') {
if (peer.id === signaling.getSessionId()) {
console.debug('Not adding ICE connection state handler for own peer', peer)
startSendingNick(peer)
} else {
setHandlerForIceConnectionStateChange(peer)
}
@ -799,7 +765,6 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
function stopPeerCheckMedia(peer) {
stopPeerCheckAudioMedia(peer)
stopPeerCheckVideoMedia(peer)
stopSendingNick(peer)
}
function startPeerCheckMedia(peer, stream) {
@ -974,12 +939,8 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
} else if (data.type === 'videoOff') {
webrtc.emit('mute', { id: peer.id, name: 'video' })
} else if (data.type === 'nickChanged') {
const payload = data.payload || ''
if (typeof (payload) === 'string') {
webrtc.emit('nick', { id: peer.id, name: data.payload })
} else {
webrtc.emit('nick', { id: peer.id, name: payload.name, userid: payload.userid })
}
const name = typeof (data.payload) === 'string' ? data.payload : data.payload.name
webrtc.emit('nick', { id: peer.id, name: name })
} else if (data.type === 'speaking' || data.type === 'stoppedSpeaking') {
// Valid known messages, but handled elsewhere
} else {
@ -1012,6 +973,50 @@ export default function initWebRTC(signaling, _callParticipantCollection, _local
sendDataChannelToAll('status', 'videoOff')
})
// Send the nick changed event via data channel and signaling
//
// The message format is different in each case. Due to historical reasons
// the payload of the data channel message is either a string that contains
// the name (if the participant is a guest) or an object with "name" and
// "userid" string fields (when the participant is a user).
//
// In the newer signaling message, on the other hand, the payload is always
// an object with only a "name" string field.
webrtc.on('nickChanged', function(name) {
let payload
if (signaling.settings.userId === null) {
payload = name
} else {
payload = {
'name': name,
'userid': signaling.settings.userId,
}
}
sendDataChannelToAll('status', 'nickChanged', payload)
// "webrtc.sendToAll" can not be used, as it only sends the signaling
// message to participants for which there is a Peer object, so the
// message may not be sent to participants without audio and video.
for (const sessionId in usersInCallMapping) {
if (!usersInCallMapping[sessionId].inCall) {
continue
} else if (sessionId === signaling.getSessionId()) {
continue
}
const message = {
to: sessionId,
roomType: 'video',
type: 'nickChanged',
payload: {
name: name,
},
}
signaling.emit('message', message)
}
})
// Local screen added.
webrtc.on('localScreenAdded', function(/* video */) {
const currentSessionId = signaling.getSessionId()