diff --git a/bigbluebutton-html5/client/compatibility/kurento-extension.js b/bigbluebutton-html5/client/compatibility/kurento-extension.js
index 4ca52d78a9..2229844ae4 100644
--- a/bigbluebutton-html5/client/compatibility/kurento-extension.js
+++ b/bigbluebutton-html5/client/compatibility/kurento-extension.js
@@ -108,34 +108,37 @@ KurentoManager.prototype.exitScreenShare = function () {
this.kurentoScreenshare.dispose();
this.kurentoScreenshare = null;
}
-
- if (typeof this.kurentoVideo !== 'undefined' && this.kurentoVideo) {
- this.exitVideo();
- }
};
KurentoManager.prototype.exitVideo = function () {
- if (typeof this.kurentoVideo !== 'undefined' && this.kurentoVideo) {
+ try {
+ if (typeof this.kurentoVideo !== 'undefined' && this.kurentoVideo) {
+ if(this.kurentoVideo.webRtcPeer) {
+ this.kurentoVideo.webRtcPeer.peerConnection.oniceconnectionstatechange = null;
+ }
- if(this.kurentoVideo.webRtcPeer) {
- this.kurentoVideo.webRtcPeer.peerConnection.oniceconnectionstatechange = null;
+ if (this.kurentoVideo.logger !== null) {
+ this.kurentoVideo.logger.info(' [exitScreenShare] Exiting screensharing viewing');
+ }
+
+ if (this.kurentoVideo.ws !== null) {
+ this.kurentoVideo.ws.onclose = function () {};
+ this.kurentoVideo.ws.close();
+ }
+
+ if (this.kurentoVideo.pingInterval) {
+ clearInterval(this.kurentoVideo.pingInterval);
+ }
+
+ this.kurentoVideo.dispose();
+ this.kurentoVideo = null;
}
-
- if (this.kurentoVideo.logger !== null) {
- this.kurentoVideo.logger.info(' [exitScreenShare] Exiting screensharing viewing');
+ }
+ catch (err) {
+ if (this.kurentoVideo) {
+ this.kurentoVideo.dispose();
+ this.kurentoVideo = null;
}
-
- if (this.kurentoVideo.ws !== null) {
- this.kurentoVideo.ws.onclose = function () {};
- this.kurentoVideo.ws.close();
- }
-
- if (this.kurentoVideo.pingInterval) {
- clearInterval(this.kurentoVideo.pingInterval);
- }
-
- this.kurentoVideo.dispose();
- this.kurentoVideo = null;
}
};
diff --git a/labs/bbb-webrtc-sfu/lib/base/BaseManager.js b/labs/bbb-webrtc-sfu/lib/base/BaseManager.js
index 9e7320b2a0..8a88e671fc 100644
--- a/labs/bbb-webrtc-sfu/lib/base/BaseManager.js
+++ b/labs/bbb-webrtc-sfu/lib/base/BaseManager.js
@@ -137,7 +137,7 @@ module.exports = class BaseManager {
}
_handleError (logPrefix, connectionId, streamId, role, error) {
- if (this._validateErrorMessage(error)) {
+ if (error && this._validateErrorMessage(error)) {
return error;
}
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..0b42746094 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(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;