Merge pull request #6058 from prlanzarin/screenshare-fix-presenter-switch

Fix screenshare edge case with presenter switch
This commit is contained in:
Anton Georgiev 2018-09-12 14:57:35 -04:00 committed by GitHub
commit 10ae980fd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 74 additions and 37 deletions

View File

@ -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;
}
};

View File

@ -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;
}

View File

@ -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",

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}
};

View File

@ -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;