mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: onForciblyReconnectSubscriber
parent
ffcb56cc0d
commit
00d64ded9b
|
@ -117,12 +117,14 @@ export class OpenVidu {
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
webrtcStatsInterval: number = -1;
|
webrtcStatsInterval: number = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
sendBrowserLogs: OpenViduLoggerConfiguration = OpenViduLoggerConfiguration.disabled;
|
sendBrowserLogs: OpenViduLoggerConfiguration = OpenViduLoggerConfiguration.disabled;
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
isPro: boolean = false;
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
|
@ -768,7 +770,8 @@ export class OpenVidu {
|
||||||
filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session),
|
filterEventDispatched: this.session.onFilterEventDispatched.bind(this.session),
|
||||||
iceCandidate: this.session.recvIceCandidate.bind(this.session),
|
iceCandidate: this.session.recvIceCandidate.bind(this.session),
|
||||||
mediaError: this.session.onMediaError.bind(this.session),
|
mediaError: this.session.onMediaError.bind(this.session),
|
||||||
masterNodeCrashedNotification: this.onMasterNodeCrashedNotification.bind(this)
|
masterNodeCrashedNotification: this.onMasterNodeCrashedNotification.bind(this),
|
||||||
|
forciblyReconnectSubscriber: this.session.onForciblyReconnectSubscriber.bind(this.session)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config);
|
this.jsonRpcClient = new RpcBuilder.clients.JsonRpcClient(config);
|
||||||
|
|
|
@ -778,8 +778,6 @@ export class Session extends EventDispatcher {
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
onParticipantLeft(event: { connectionId: string, reason: string }): void {
|
onParticipantLeft(event: { connectionId: string, reason: string }): void {
|
||||||
|
|
||||||
if (this.remoteConnections.size > 0) {
|
|
||||||
this.getRemoteConnection(event.connectionId, 'onParticipantLeft').then(connection => {
|
this.getRemoteConnection(event.connectionId, 'onParticipantLeft').then(connection => {
|
||||||
if (!!connection.stream) {
|
if (!!connection.stream) {
|
||||||
const stream = connection.stream;
|
const stream = connection.stream;
|
||||||
|
@ -797,7 +795,6 @@ export class Session extends EventDispatcher {
|
||||||
logger.error(openViduError);
|
logger.error(openViduError);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
|
@ -1123,6 +1120,61 @@ export class Session extends EventDispatcher {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
onForciblyReconnectSubscriber(event: { connectionId: string, streamId: string, sdpOffer: string }): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.getRemoteConnection(event.connectionId, 'onForciblyReconnectSubscriber')
|
||||||
|
.then(connection => {
|
||||||
|
if (!!connection.stream && connection.stream.streamId === event.streamId) {
|
||||||
|
const stream = connection.stream;
|
||||||
|
|
||||||
|
if (stream.setupReconnectionEventEmitter(resolve, reject)) {
|
||||||
|
// Ongoing reconnection
|
||||||
|
// Wait for the event emitter to be free (with success or error) and call the method again
|
||||||
|
if (stream.reconnectionEventEmitter!['onForciblyReconnectSubscriberLastEvent'] != null) {
|
||||||
|
// Two or more onForciblyReconnectSubscriber events were received while a reconnection process
|
||||||
|
// of the subscriber was already taking place. Always use the last one to retry the re-subscription
|
||||||
|
// process, as that SDP offer will be the only one available at the server side. Ignore previous ones
|
||||||
|
stream.reconnectionEventEmitter!['onForciblyReconnectSubscriberLastEvent'] = event;
|
||||||
|
reject('Ongoing forced subscriber reconnection');
|
||||||
|
} else {
|
||||||
|
// One onForciblyReconnectSubscriber even has been received while a reconnection process
|
||||||
|
// of the subscriber was already taking place. Set up a listener to wait for it to retry the
|
||||||
|
// forced reconnection process
|
||||||
|
stream.reconnectionEventEmitter!['onForciblyReconnectSubscriberLastEvent'] = event;
|
||||||
|
const callback = () => {
|
||||||
|
const eventAux = stream.reconnectionEventEmitter!['onForciblyReconnectSubscriberLastEvent'];
|
||||||
|
delete stream.reconnectionEventEmitter!['onForciblyReconnectSubscriberLastEvent'];
|
||||||
|
this.onForciblyReconnectSubscriber(eventAux);
|
||||||
|
}
|
||||||
|
stream.reconnectionEventEmitter!.once('success', () => {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
stream.reconnectionEventEmitter!.once('error', () => {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.completeWebRtcPeerReceive(true, event.sdpOffer)
|
||||||
|
.then(() => stream.finalResolveForSubscription(true, resolve))
|
||||||
|
.catch(error => stream.finalRejectForSubscription(true, `Error while forcibly reconnecting remote stream ${event.streamId}: ${error.toString()}`, reject));
|
||||||
|
} else {
|
||||||
|
const errMsg = "No stream with streamId '" + event.streamId + "' found for connection '" + event.connectionId + "' on 'streamPropertyChanged' event";
|
||||||
|
logger.error(errMsg);
|
||||||
|
reject(errMsg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(openViduError => {
|
||||||
|
logger.error(openViduError);
|
||||||
|
reject(openViduError);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
|
@ -1463,6 +1515,7 @@ export class Session extends EventDispatcher {
|
||||||
if (!!sendBrowserLogs) {
|
if (!!sendBrowserLogs) {
|
||||||
this.openvidu.sendBrowserLogs = sendBrowserLogs;
|
this.openvidu.sendBrowserLogs = sendBrowserLogs;
|
||||||
}
|
}
|
||||||
|
this.openvidu.isPro = !!webrtcStatsInterval && !!sendBrowserLogs;
|
||||||
|
|
||||||
this.openvidu.wsUri = 'wss://' + url.host + '/openvidu';
|
this.openvidu.wsUri = 'wss://' + url.host + '/openvidu';
|
||||||
this.openvidu.httpUri = 'https://' + url.host;
|
this.openvidu.httpUri = 'https://' + url.host;
|
||||||
|
|
|
@ -818,22 +818,33 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
initWebRtcPeerSend(reconnect: boolean): Promise<void> {
|
setupReconnectionEventEmitter(resolve: (value: void | PromiseLike<void>) => void, reject: (reason?: any) => void): boolean {
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
if (reconnect) {
|
|
||||||
if (this.reconnectionEventEmitter == undefined) {
|
if (this.reconnectionEventEmitter == undefined) {
|
||||||
// There is no ongoing reconnection
|
// There is no ongoing reconnection
|
||||||
this.reconnectionEventEmitter = new EventEmitter();
|
this.reconnectionEventEmitter = new EventEmitter();
|
||||||
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// Ongoing reconnection
|
// Ongoing reconnection
|
||||||
console.warn(`Trying to reconnect stream ${this.streamId} (Publisher) but an ongoing reconnection process is active. Waiting for response...`);
|
console.warn(`Trying to reconnect stream ${this.streamId} (${this.isLocal() ? 'Publisher' : 'Subscriber'}) but an ongoing reconnection process is active. Waiting for response...`);
|
||||||
this.reconnectionEventEmitter.once('success', () => {
|
this.reconnectionEventEmitter.once('success', () => {
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
this.reconnectionEventEmitter.once('error', error => {
|
this.reconnectionEventEmitter.once('error', error => {
|
||||||
reject(error);
|
reject(error);
|
||||||
});
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
initWebRtcPeerSend(reconnect: boolean): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
if (reconnect) {
|
||||||
|
if (this.setupReconnectionEventEmitter(resolve, reject)) {
|
||||||
|
// Ongoing reconnection
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -959,27 +970,7 @@ export class Stream {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
initWebRtcPeerReceive(reconnect: boolean): Promise<void> {
|
finalResolveForSubscription(reconnect: boolean, resolve: (value: void | PromiseLike<void>) => void) {
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
if (reconnect) {
|
|
||||||
if (this.reconnectionEventEmitter == undefined) {
|
|
||||||
// There is no ongoing reconnection
|
|
||||||
this.reconnectionEventEmitter = new EventEmitter();
|
|
||||||
} else {
|
|
||||||
// Ongoing reconnection
|
|
||||||
console.warn(`Trying to reconnect stream ${this.streamId} (Subscriber) but an ongoing reconnection process is active. Waiting for response...`);
|
|
||||||
this.reconnectionEventEmitter.once('success', () => {
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
this.reconnectionEventEmitter.once('error', error => {
|
|
||||||
reject(error);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const finalResolve = () => {
|
|
||||||
logger.info("'Subscriber' (" + this.streamId + ") successfully " + (reconnect ? "reconnected" : "subscribed"));
|
logger.info("'Subscriber' (" + this.streamId + ") successfully " + (reconnect ? "reconnected" : "subscribed"));
|
||||||
this.remotePeerSuccessfullyEstablished(reconnect);
|
this.remotePeerSuccessfullyEstablished(reconnect);
|
||||||
this.initWebRtcStats();
|
this.initWebRtcStats();
|
||||||
|
@ -990,7 +981,11 @@ export class Stream {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
const finalReject = error => {
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
finalRejectForSubscription(reconnect: boolean, error: any, reject: (reason?: any) => void) {
|
||||||
|
logger.error("Error for 'Subscriber' (" + this.streamId + ") while trying to " + (reconnect ? "reconnect" : "subscribe") + ": " + error.toString());
|
||||||
if (reconnect) {
|
if (reconnect) {
|
||||||
this.reconnectionEventEmitter?.emitEvent('error', [error]);
|
this.reconnectionEventEmitter?.emitEvent('error', [error]);
|
||||||
delete this.reconnectionEventEmitter;
|
delete this.reconnectionEventEmitter;
|
||||||
|
@ -998,21 +993,34 @@ export class Stream {
|
||||||
reject(error);
|
reject(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
initWebRtcPeerReceive(reconnect: boolean): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
if (reconnect) {
|
||||||
|
if (this.setupReconnectionEventEmitter(resolve, reject)) {
|
||||||
|
// Ongoing reconnection
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (this.session.openvidu.mediaServer === 'mediasoup') {
|
if (this.session.openvidu.mediaServer === 'mediasoup') {
|
||||||
|
|
||||||
// Server initiates negotiation
|
// Server initiates negotiation
|
||||||
|
|
||||||
this.initWebRtcPeerReceiveFromServer(reconnect)
|
this.initWebRtcPeerReceiveFromServer(reconnect)
|
||||||
.then(() => finalResolve())
|
.then(() => this.finalResolveForSubscription(reconnect, resolve))
|
||||||
.catch(error => finalReject(error));
|
.catch(error => this.finalRejectForSubscription(reconnect, error, reject));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Client initiates negotiation
|
// Client initiates negotiation
|
||||||
|
|
||||||
this.initWebRtcPeerReceiveFromClient(reconnect)
|
this.initWebRtcPeerReceiveFromClient(reconnect)
|
||||||
.then(() => finalResolve())
|
.then(() => this.finalResolveForSubscription(reconnect, resolve))
|
||||||
.catch(error => finalReject(error));
|
.catch(error => this.finalRejectForSubscription(reconnect, error, reject));
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1320,7 +1328,10 @@ export class Stream {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
private initWebRtcStats(): void {
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
initWebRtcStats(): void {
|
||||||
this.webRtcStats = new WebRtcStats(this);
|
this.webRtcStats = new WebRtcStats(this);
|
||||||
this.webRtcStats.initWebRtcStats();
|
this.webRtcStats.initWebRtcStats();
|
||||||
|
|
||||||
|
|
|
@ -28,10 +28,10 @@ export class OpenViduLogger {
|
||||||
*/
|
*/
|
||||||
static configureJSNLog(openVidu: OpenVidu, token: string) {
|
static configureJSNLog(openVidu: OpenVidu, token: string) {
|
||||||
try {
|
try {
|
||||||
// If dev mode
|
// If dev mode or...
|
||||||
if ((window['LOG_JSNLOG_RESULTS']) ||
|
if ((window['LOG_JSNLOG_RESULTS']) ||
|
||||||
// If instance is created and it is OpenVidu Pro
|
// If instance is created and it is OpenVidu Pro
|
||||||
(this.instance && openVidu.webrtcStatsInterval > -1
|
(this.instance && openVidu.isPro
|
||||||
// If logs are enabled
|
// If logs are enabled
|
||||||
&& this.instance.isOpenViduBrowserLogsDebugActive(openVidu)
|
&& this.instance.isOpenViduBrowserLogsDebugActive(openVidu)
|
||||||
// Only reconfigure it if session or finalUserId has changed
|
// Only reconfigure it if session or finalUserId has changed
|
||||||
|
@ -159,9 +159,9 @@ export class OpenViduLogger {
|
||||||
|
|
||||||
// Return console functions with jsnlog integration
|
// Return console functions with jsnlog integration
|
||||||
private getConsoleWithJSNLog() {
|
private getConsoleWithJSNLog() {
|
||||||
return function(openViduLogger: OpenViduLogger){
|
return function (openViduLogger: OpenViduLogger) {
|
||||||
return {
|
return {
|
||||||
log: function(...args){
|
log: function (...args) {
|
||||||
openViduLogger.defaultConsoleLogger.log.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
|
openViduLogger.defaultConsoleLogger.log.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
|
||||||
if (openViduLogger.isJSNLogSetup) {
|
if (openViduLogger.isJSNLogSetup) {
|
||||||
JL().info(arguments);
|
JL().info(arguments);
|
||||||
|
@ -173,7 +173,7 @@ export class OpenViduLogger {
|
||||||
JL().info(arguments);
|
JL().info(arguments);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
debug: function(...args) {
|
debug: function (...args) {
|
||||||
openViduLogger.defaultConsoleLogger.debug.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
|
openViduLogger.defaultConsoleLogger.debug.apply(openViduLogger.defaultConsoleLogger.logger, arguments);
|
||||||
},
|
},
|
||||||
warn: function (...args) {
|
warn: function (...args) {
|
||||||
|
@ -202,7 +202,7 @@ export class OpenViduLogger {
|
||||||
}
|
}
|
||||||
|
|
||||||
private disableLogger() {
|
private disableLogger() {
|
||||||
JL.setOptions({enabled: false});
|
JL.setOptions({ enabled: false });
|
||||||
this.isJSNLogSetup = false;
|
this.isJSNLogSetup = false;
|
||||||
this.loggingSessionId = undefined;
|
this.loggingSessionId = undefined;
|
||||||
this.currentAppender = undefined;
|
this.currentAppender = undefined;
|
||||||
|
|
Loading…
Reference in New Issue