Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Calviño Sánchez <danxuliu@gmail.com>2021-10-28 20:45:11 +0300
committerJoas Schilling <coding@schilljs.com>2021-11-03 15:10:34 +0300
commit1e1cd5e25f785c32f33fc8af63b9d887d9d2a408 (patch)
tree89a4e35b6b03f7a20cb9ff2effa2e0514550f6ff /src
parenta4a0e46219efaf506f07423a9d3757259890c4c6 (diff)
Leave call when participant was remotely disconnected from the call
Currently whether the local user is in the call or not from the point of view of the Nextcloud server is mostly ignored; the UI is based only on whether the user explicitly joined or left the call. The reason is that after the user joined the response from a previous request to get the room information done when the user had not joined yet could be received, so honouring that could make the UI jump between "in the call" and "not in the call" (as it happened in older versions). However, in the WebRTC related code whether the local user is in the call or not is only based on the user events sent by the signaling server, so in that case the state is always up to date. Due to this, it is possible to detect whether the local user was kicked out from the call by a moderator (for example, because the call was ended for everyone) by comparing the local state ("localUserInCall", which is updated when locally joining and leaving a call) with the remote state provided by the signaling server. Note that there is no rollback of "localUserInCall" if the join or leave call request fails; the error is currently ignored by other parts of the code, so handling it here does not provide any benefit. An alternative approach would have been to ignore the "in call" state provided by the server while a "join call" request is on-going, so the local state and the server state would match except when the user was kicked out from the call. This would have required deeper changes, so even if it could be a better approach in the end for now the simpler (but less clean) approach was used. Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Diffstat (limited to 'src')
-rw-r--r--src/utils/signaling.js4
-rw-r--r--src/utils/webrtc/webrtc.js36
2 files changed, 40 insertions, 0 deletions
diff --git a/src/utils/signaling.js b/src/utils/signaling.js
index 28b699c10..98edcb0bb 100644
--- a/src/utils/signaling.js
+++ b/src/utils/signaling.js
@@ -266,6 +266,8 @@ Signaling.Base.prototype._joinCallSuccess = function(/* token */) {
Signaling.Base.prototype.joinCall = function(token, flags) {
return new Promise((resolve, reject) => {
+ this._trigger('beforeJoinCall', [token])
+
axios.post(generateOcsUrl('apps/spreed/api/v4/call/{token}', { token }), {
flags,
})
@@ -318,6 +320,8 @@ Signaling.Base.prototype.leaveCall = function(token, keepToken, all = false) {
return
}
+ this._trigger('beforeLeaveCall', [token, keepToken])
+
axios.delete(generateOcsUrl('apps/spreed/api/v4/call/{token}', { token }), {
data: {
all,
diff --git a/src/utils/webrtc/webrtc.js b/src/utils/webrtc/webrtc.js
index 20f5c1e62..e06bba446 100644
--- a/src/utils/webrtc/webrtc.js
+++ b/src/utils/webrtc/webrtc.js
@@ -50,6 +50,10 @@ let usersInCallMapping = {}
let ownPeer = null
let ownScreenPeer = null
let selfInCall = PARTICIPANT.CALL_FLAG.DISCONNECTED
+// Special variable to know when the local user explicitly joined and left the
+// call; this is needed to know when the user was kicked out from the call by a
+// moderator.
+let localUserInCall = false
const delayedConnectionToPeer = []
let callParticipantCollection = null
let localCallParticipantModel = null
@@ -469,6 +473,24 @@ function usersInCallChanged(signaling, users) {
Sounds.playLeave(true)
}
+ // Besides the participant state it also needs to be checked whether the
+ // local user left the call already or not (either explicitly or due to a
+ // forced reconnection) to avoid trying to leave the call twice in the
+ // store.
+ if (previousSelfInCall !== PARTICIPANT.CALL_FLAG.DISCONNECTED
+ && selfInCall === PARTICIPANT.CALL_FLAG.DISCONNECTED
+ && localUserInCall) {
+ console.info('Force leaving the call for current participant')
+
+ store.dispatch('leaveCall', {
+ token: store.getters.getToken(),
+ participantIdentifier: store.getters.getParticipantIdentifier(),
+ })
+
+ // Do not return to disconnect already from the other participants
+ // without waiting for another signaling event about changed users.
+ }
+
if (selfInCall === PARTICIPANT.CALL_FLAG.DISCONNECTED) {
// Own session is no longer in the call, disconnect from all others.
usersChanged(signaling, [], previousUsersInRoom)
@@ -534,6 +556,20 @@ export default function initWebRtc(signaling, _callParticipantCollection, _local
})
usersInCallChanged(signaling, usersInCallMapping)
})
+ signaling.on('beforeJoinCall', function(token, reconnect) {
+ // The user needs to be set as in the call before the request is
+ // actually done to also cover the (unlikely) case that the request
+ // takes too long to return and the associated signaling message
+ // is received before the "join call" request ends.
+ localUserInCall = true
+ })
+ signaling.on('beforeLeaveCall', function(token, reconnect) {
+ // The user needs to be set as not in the call before the request is
+ // actually done to also cover the (unlikely) case that the request
+ // takes too long to return and the associated signaling message
+ // is received before the "leave call" request ends.
+ localUserInCall = false
+ })
signaling.on('leaveCall', function(token, reconnect) {
// When the MCU is used and there is a connection error the call is
// left and then joined again to perform the reconnection. In those