Added SFU error handling in video-provider component with localized messages

This commit is contained in:
prlanzarin 2018-07-20 19:34:50 +00:00
parent 20d66e04c2
commit 75f70ad06c
7 changed files with 92 additions and 49 deletions

View File

@ -6,7 +6,7 @@ const kurentoHandler = null;
const SEND_ROLE = "send";
const RECV_ROLE = "recv";
const SFU_APP = "screenshare";
const ON_ICE_CANDIDATE_MSG = "onIceCandidate";
const ON_ICE_CANDIDATE_MSG = "iceCandidate";
const START_MSG = "start";
const START_RESPONSE_MSG = "startResponse";
const PING_INTERVAL = 15000;

View File

@ -3,13 +3,6 @@ const isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
const isChrome = !!window.chrome && !isOpera;
const isSafari = navigator.userAgent.indexOf('Safari') >= 0 && !isChrome;
const kurentoHandler = null;
const SEND_ROLE = "send";
const RECV_ROLE = "recv";
const SFU_APP = "screenshare";
const ON_ICE_CANDIDATE_MSG = "onIceCandidate";
const START_MSG = "start";
const START_RESPONSE_MSG = "startResponse";
const PING_INTERVAL = 15000;
Kurento = function (
tag,
@ -37,6 +30,13 @@ Kurento = function (
Object.assign(this, options);
this.SEND_ROLE = "send";
this.RECV_ROLE = "recv";
this.SFU_APP = "screenshare";
this.ON_ICE_CANDIDATE_MSG = "iceCandidate";
this.PING_INTERVAL = 15000;
if (this.wsUrl == null) {
this.defaultPath = 'bbb-webrtc-sfu';
this.hostName = window.location.hostname;
@ -218,7 +218,7 @@ Kurento.prototype.init = function () {
self.onFail('Websocket connection error');
};
this.ws.onopen = function () {
self.pingInterval = setInterval(self.ping.bind(self), PING_INTERVAL);
self.pingInterval = setInterval(self.ping.bind(self), self.PING_INTERVAL);
self.mediaCallback();
};
} else { console.log('this browser does not support websockets'); }
@ -259,10 +259,10 @@ Kurento.prototype.startResponse = function (message) {
console.warn(`Call not accepted for the following reason: ${errorMsg}`);
switch (message.type) {
case 'screenshare':
if (message.role === SEND_ROLE) {
if (message.role === this.SEND_ROLE) {
kurentoManager.exitScreenShare();
}
else if (message.role === RECV_ROLE) {
else if (message.role === this.RECV_ROLE) {
kurentoManager.exitVideo();
}
break;
@ -287,8 +287,8 @@ Kurento.prototype.onOfferPresenter = function (error, offerSdp) {
const message = {
id: 'start',
type: SFU_APP,
role: SEND_ROLE,
type: this.SFU_APP,
role: this.SEND_ROLE,
internalMeetingId: self.internalMeetingId,
voiceBridge: self.voiceBridge,
callerName: self.userId,
@ -317,7 +317,7 @@ Kurento.prototype.startScreensharing = function () {
const options = {
localVideo: document.getElementById(this.renderTag),
onicecandidate: (candidate) => {
this.onIceCandidate(candidate, SEND_ROLE);
this.onIceCandidate(candidate, this.SEND_ROLE);
},
sendSource: 'desktop',
};
@ -361,9 +361,9 @@ Kurento.prototype.onIceCandidate = function (candidate, role) {
console.log(`Local candidate${JSON.stringify(candidate)}`);
const message = {
id: ON_ICE_CANDIDATE_MSG,
id: this.ON_ICE_CANDIDATE_MSG,
role: role,
type: SFU_APP,
type: this.SFU_APP,
voiceBridge: self.voiceBridge,
candidate,
callerName: self.userId,
@ -389,7 +389,7 @@ Kurento.prototype.viewer = function () {
},
remoteVideo: document.getElementById(this.renderTag),
onicecandidate: (candidate) => {
this.onIceCandidate(candidate, RECV_ROLE);
this.onIceCandidate(candidate, this.RECV_ROLE);
}
}
@ -413,8 +413,8 @@ Kurento.prototype.onOfferViewer = function (error, offerSdp) {
}
const message = {
id: 'start',
type: SFU_APP,
role: RECV_ROLE,
type: this.SFU_APP,
role: this.RECV_ROLE,
internalMeetingId: self.internalMeetingId,
voiceBridge: self.voiceBridge,
callerName: self.userId,
@ -467,7 +467,7 @@ Kurento.prototype.onListenOnlyIceCandidate = function (candidate) {
console.debug("[onListenOnlyIceCandidate]", JSON.stringify(candidate));
var message = {
id : 'iceCandidate',
id : this.ON_ICE_CANDIDATE_MSG,
type: 'audio',
role: 'viewer',
voiceBridge: self.voiceBridge,

View File

@ -7,7 +7,7 @@ import VideoService from './service';
import VideoList from './video-list/component';
import { fetchWebRTCMappedStunTurnServers } from '/imports/utils/fetchStunTurnServers';
const intlMessages = defineMessages({
const intlClientErrors = defineMessages({
iceCandidateError: {
id: 'app.video.iceCandidateError',
description: 'Error message for ice candidate fail',
@ -24,9 +24,6 @@ const intlMessages = defineMessages({
id: 'app.video.chromeExtensionErrorLink',
description: 'Error message for Chrome Extension not installed',
},
});
const intlMediaErrorsMessages = defineMessages({
permissionError: {
id: 'app.video.permissionError',
description: 'Error message for webcam permission',
@ -47,10 +44,41 @@ const intlMediaErrorsMessages = defineMessages({
id: 'app.video.notReadableError',
description: 'error message When the webcam is being used by other software',
},
1000: {
id: 'app.video.mediaServerOffline',
});
const intlSFUErrors = defineMessages({
2000: {
id: 'app.sfu.mediaServerConnectionError2000',
description: 'Error message fired when the SFU cannot connect to the media server',
},
2001: {
id: 'app.sfu.mediaServerOffline2001',
description: 'error message when kurento is offline',
},
2002: {
id: 'app.sfu.mediaServerNoResources2002',
description: 'Error message fired when the media server lacks disk, CPU or FDs',
},
2003: {
id: 'app.sfu.mediaServerRequestTimeout2003',
description: "Error message fired when requests are timing out due to lack of resources",
},
2021: {
id: 'app.sfu.serverIceGatheringFailed2021',
description: 'Error message fired when the server cannot enact ICE gathering',
},
2022: {
id: 'app.sfu.serverIceStateFailed2022',
description: 'Error message fired when the server endpoint transitioned to a FAILED ICE state',
},
2202: {
id: 'app.sfu.invalidSdp2202',
description: 'Error message fired when the clients provides an invalid SDP',
},
2203: {
id: 'app.sfu.noAvailableCodec2203',
description: 'Error message fired when the server has no available codec for the client',
}
});
const CAMERA_SHARE_FAILED_WAIT_TIME = 15000;
@ -235,7 +263,7 @@ class VideoProvider extends Component {
case 'error':
default:
this.handleError(parsedMessage);
this.handleSFUError(parsedMessage);
break;
}
}
@ -291,6 +319,9 @@ class VideoProvider extends Component {
}
});
} else {
if (webRtcPeer.iceQueue == null) {
webRtcPeer.iceQueue = [];
}
webRtcPeer.iceQueue.push(message.candidate);
}
} else {
@ -382,7 +413,9 @@ class VideoProvider extends Component {
peer.started = false;
peer.attached = false;
peer.didSDPAnswered = false;
peer.iceQueue = [];
if (peer.iceQueue == null) {
peer.iceQueue = [];
}
if (error) {
return this._webRTCOnError(error, id, shareWebcam);
@ -420,7 +453,7 @@ class VideoProvider extends Component {
log('error', `Camera share has not suceeded in ${CAMERA_SHARE_FAILED_WAIT_TIME} for ${id}`);
if (this.props.userId === id) {
this.notifyError(intl.formatMessage(intlMessages.sharingError));
this.notifyError(intl.formatMessage(intlClientErrors.sharingError));
this.unshareWebcam();
this.destroyWebRTCPeer(id);
} else {
@ -445,7 +478,7 @@ class VideoProvider extends Component {
const candidate = peer.iceQueue.shift();
peer.addIceCandidate(candidate, (err) => {
if (err) {
this.notifyError(intl.formatMessage(intlMessages.iceCandidateError));
this.notifyError(intl.formatMessage(intlClientErrors.iceCandidateError));
return console.log(`Error adding candidate: ${err}`);
}
});
@ -457,8 +490,8 @@ class VideoProvider extends Component {
log('error', ' WebRTC peerObj create error');
log('error', JSON.stringify(error));
const errorMessage = intlMediaErrorsMessages[error.name]
|| intlMediaErrorsMessages.permissionError;
const errorMessage = intlClientErrors[error.name]
|| intlClientErrors.permissionError;
this.notifyError(intl.formatMessage(errorMessage));
/* This notification error is displayed considering kurento-utils
* returned the error 'The request is not allowed by the user agent
@ -761,19 +794,18 @@ class VideoProvider extends Component {
}
}
handleError(message) {
handleSFUError(message) {
const { intl } = this.props;
const { userId } = this.props;
if (message.cameraId === userId) {
const { code, reason } = message;
log('debug', 'Received error from SFU:', code, reason, message.streamId, userId);
if (message.streamId === userId) {
this.unshareWebcam();
this.notifyError(intl.formatMessage(intlMediaErrorsMessages[message.message]
|| intlMessages.sharingError));
this.notifyError(intl.formatMessage(intlSFUErrors[code]
|| intlClientErrors.sharingError));
} else {
this.stopWebRTCPeer(message.cameraId);
}
log('debug', 'Handle error --------------------->');
log('debug', message.message);
}
notifyError(message) {
@ -789,7 +821,7 @@ class VideoProvider extends Component {
VideoService.joiningVideo();
} else {
log('debug', 'Error on sharing webcam');
this.notifyError(intl.formatMessage(intlMessages.sharingError));
this.notifyError(intl.formatMessage(intlClientErrors.sharingError));
}
}

View File

@ -324,7 +324,6 @@
"app.video.notAllowed": "Missing permission for share webcam, please make sure your browser permissions",
"app.video.notSupportedError": "Can share webcam video only with safe sources, make sure your SSL certificate is valid",
"app.video.notReadableError": "Could not get webcam video. Please make sure another program is not using the webcam ",
"app.video.mediaServerOffline": "Media server is offline. Please try again later.",
"app.video.swapCam": "Swap",
"app.video.swapCamDesc": "swap the direction of webcams",
"app.video.videoMenu": "Video menu",
@ -345,6 +344,15 @@
"app.video.stats.rtt": "RTT",
"app.video.stats.encodeUsagePercent": "Encode usage",
"app.video.stats.currentDelay": "Current delay",
"app.sfu.mediaServerConnectionError2000": "Error 2000: Unable to connect to media server",
"app.sfu.mediaServerOffline2001": "Error 2001: Media server is offline. Please try again later.",
"app.sfu.mediaServerNoResources2002": "Error 2002: Media server has no available resources",
"app.sfu.mediaServerRequestTimeout2003": , "Error 2003: Media server requests are timing out",
"app.sfu.serverIceGatheringFailed2021": "Error 2021: Media server cannot gather ICE candidates",
"app.sfu.serverIceGatheringFailed2022": "Error 2022: Media server ICE connection failed",
"app.sfu.invalidSdp2202":"Error 2202: Client generated an invalid SDP",
"app.sfu.noAvailableCodec2203": "Error 2203: Server could not find an appropriate codec",
"app.meeting.endNotification.ok.label": "OK",
"app.whiteboard.toolbar.tools": "Tools",
"app.whiteboard.toolbar.tools.pointer": "Pointer",

View File

@ -4,9 +4,11 @@ const errorCodes = {
2000: "MEDIA_SERVER_CONNECTION_ERROR",
2001: "MEDIA_SERVER_OFFLINE",
2002: "MEDIA_SERVER_NO_RESOURCES",
2003: "ICE_ADD_CANDIDATE_FAILED",
2004: "ICE_GATHERING_FAILED",
2005: "MEDIA_SERVER_REQUEST_TIMEOUT",
2003: "MEDIA_SERVER_REQUEST_TIMEOUT",
2004: "MEDIA_SERVER_GENERIC_ERROR",
2020: "ICE_ADD_CANDIDATE_FAILED",
2021: "ICE_GATHERING_FAILED",
2022: "ICE_STATE_FAILED",
2200: "MEDIA_GENERIC_ERROR",
2201: "MEDIA_NOT_FOUND",
2202: "MEDIA_INVALID_SDP",

View File

@ -52,10 +52,11 @@ exports.ERROR.MAX_CODE = 2999;
exports.ERROR.CONNECTION_ERROR = { code: 2000, message: "MEDIA_SERVER_CONNECTION_ERROR" };
exports.ERROR.MEDIA_SERVER_OFFLINE = { code: 2001, message: "MEDIA_SERVER_OFFLINE" };
exports.ERROR.MEDIA_SERVER_NO_RESOURCES = { code: 2002, message: "MEDIA_SERVER_NO_RESOURCES" };
exports.ERROR.ICE_CANDIDATE_FAILED = { code: 2003, message: "ICE_ADD_CANDIDATE_FAILED" };
exports.ERROR.ICE_GATHERING_FAILED = { code: 2004, message: "ICE_GATHERING_FAILED" };
exports.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT = { code: 2005, message: "MEDIA_SERVER_REQUEST_TIMEOUT" };
exports.ERROR.MEDIA_SERVER_GENERIC_ERROR = { code: 2006, message: "MEDIA_SERVER_GENERIC_ERROR" };
exports.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT = { code: 2003, message: "MEDIA_SERVER_REQUEST_TIMEOUT" };
exports.ERROR.MEDIA_SERVER_GENERIC_ERROR = { code: 2019, message: "MEDIA_SERVER_GENERIC_ERROR" };
exports.ERROR.ICE_CANDIDATE_FAILED = { code: 2020, message: "ICE_ADD_CANDIDATE_FAILED" };
exports.ERROR.ICE_GATHERING_FAILED = { code: 2021, message: "ICE_GATHERING_FAILED" };
exports.ERROR.ICE_STATE_FAILED = { code: 2022, message: "ICE_STATE_FAILED" };
exports.ERROR.ROOM_GENERIC_ERROR = { code: 2100, message: "ROOM_GENNERIC_ERROR" };
exports.ERROR.ROOM_NOT_FOUND = { code: 2101, message: "ROOM_NOT_FOUND" };

View File

@ -99,7 +99,7 @@ module.exports = class VideoManager extends BaseManager {
}), C.FROM_VIDEO);
}
catch (err) {
const errorMessage = this._handleError(this._logPrefix, connectionId, cameraId, role, error);
const errorMessage = this._handleError(this._logPrefix, connectionId, message.cameraId, role, err);
return this._bbbGW.publish(JSON.stringify({
...errorMessage
}), C.FROM_VIDEO);