From 3fa8c1c7b68bdbe9291e4ce67e0ed07500ec1934 Mon Sep 17 00:00:00 2001 From: prlanzarin <prlanzarin@inf.ufrgs.br> Date: Tue, 11 Sep 2018 18:11:52 +0000 Subject: [PATCH] Fix inconsistent screenshare state on presenter switch during ongoing negotiation --- .../lib/bbb/messages/Constants.js | 3 +- labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js | 5 +++ .../WebsocketConnectionManager.js | 10 ++++- .../lib/screenshare/ScreenshareManager.js | 39 +++++++++++++------ .../lib/screenshare/screenshare.js | 5 +++ 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js b/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js index f2d481dcf2..038a0c01dd 100644 --- a/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js +++ b/labs/bbb-webrtc-sfu/lib/bbb/messages/Constants.js @@ -69,10 +69,9 @@ const config = require('config'); STOP_TRANSCODER_RESP_2x: "StopTranscoderSysRespMsg", GLOBAL_AUDIO_CONNECTED_2x: "UserConnectedToGlobalAudioMsg", GLOBAL_AUDIO_DISCONNECTED_2x: "UserDisconnectedFromGlobalAudioMsg", - // TODO: Check if this is the correct message in BBB 2.x DICONNECT_ALL_USERS_2x: "DisconnectAllClientsSysMsg", - USER_CAM_BROADCAST_STOPPED_2x: "UserBroadcastCamStopMsg", + PRESENTER_ASSIGNED_2x: "PresenterAssignedEvtMsg", STREAM_IS_RECORDED: "StreamIsRecordedMsg", diff --git a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js index f55ba1153d..bf6c4d062f 100644 --- a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js +++ b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js @@ -105,6 +105,11 @@ module.exports = class BigBlueButtonGW extends EventEmitter { payload[C.MEETING_ID_2x] = header[C.MEETING_ID_2x]; this.emit(C.DICONNECT_ALL_USERS_2x, payload); break; + case C.PRESENTER_ASSIGNED_2x: + meetingId = header[C.MEETING_ID_2x]; + payload[C.MEETING_ID_2x] = meetingId; + this.emit(C.PRESENTER_ASSIGNED_2x+meetingId, payload); + break; default: this.emit(C.GATEWAY_MESSAGE, msg); } diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js index dafc004073..b0fbcc3ae7 100644 --- a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js +++ b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js @@ -29,7 +29,15 @@ module.exports = class WebsocketConnectionManager { const connectionId = data? data.connectionId : null; const ws = this.webSockets[connectionId]; if (ws) { - this.sendMessage(ws, data); + if (data.id === 'close') { + try { + ws.close(); + } catch (err) { + Logger.warn('[WebsocketConnectionManager] Error on closing WS for', connectionId, err) + } + } else { + this.sendMessage(ws, data); + } } } diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js index f98c989838..2353a1fec8 100644 --- a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js +++ b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js @@ -70,6 +70,19 @@ module.exports = class ScreenshareManager extends BaseManager { this._stopSession(sessionId); }); + // listen for presenter change to avoid inconsistent states on reconnection + if (role === C.SEND_ROLE) { + this._bbbGW.once(C.PRESENTER_ASSIGNED_2x+message.internalMeetingId, async (payload) => { + Logger.info(this._logPrefix, "Presenter changed, forcibly closing screensharing session at", message.internalMeetingId); + await this.closeSession(session, connectionId, role, sessionId); + this._bbbGW.publish(JSON.stringify({ + connectionId: connectionId, + type: C.SCREENSHARE_APP, + id : 'close', + }), C.FROM_SCREENSHARE); + }); + } + Logger.info(this._logPrefix, "Sending startResponse to peer", sessionId, "for connection", session._id); } catch (error) { @@ -101,17 +114,7 @@ module.exports = class ScreenshareManager extends BaseManager { case 'close': Logger.info(this._logPrefix, 'Connection ' + connectionId + ' closed'); - - if (session && session.constructor == Screenshare) { - if (role === C.SEND_ROLE && session) { - Logger.info(this._logPrefix, "Stopping presenter " + sessionId); - this._stopSession(sessionId); - } - if (role === C.RECV_ROLE && session) { - Logger.info(this._logPrefix, "Stopping viewer " + sessionId); - session.stopViewer(message.connectionId); - } - } + this.closeSession(session, connectionId, role, sessionId); break; default: @@ -122,4 +125,18 @@ module.exports = class ScreenshareManager extends BaseManager { break; } } + + async closeSession (session, connectionId, role, sessionId) { + if (session && session.constructor == Screenshare) { + if (role === C.SEND_ROLE && session) { + Logger.info(this._logPrefix, "Stopping presenter " + sessionId); + await this._stopSession(sessionId); + return; + } + if (role === C.RECV_ROLE && session) { + Logger.info(this._logPrefix, "Stopping viewer " + sessionId); + await session.stopViewer(message.connectionId); + } + } + } }; diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js index aeab9fc3af..bfb22a0208 100644 --- a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js +++ b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js @@ -227,6 +227,8 @@ module.exports = class Screenshare extends BaseProvider { start (sessionId, connectionId, sdpOffer, userId, role) { return new Promise(async (resolve, reject) => { + this._status = C.MEDIA_STARTING; + // Forces H264 with a possible preferred profile if (FORCE_H264) { sdpOffer = h264_sdp.transform(sdpOffer, PREFERRED_H264_PROFILE); @@ -347,6 +349,9 @@ module.exports = class Screenshare extends BaseProvider { stop () { return new Promise(async (resolve, reject) => { try { + if (this._status === C.MEDIA_STOPPED) { + return resolve(); + } Logger.info('[screnshare] Stopping and releasing endpoints for MCS user', this.mcsUserId); await this._stopScreensharing(); this._status = C.MEDIA_STOPPED; -- GitLab