openvidu-browser: updated package.json. forceMediaReconnectionAfterNetworkDrop

This commit is contained in:
pabloFuente 2020-02-19 09:35:10 +01:00
parent d0c851d0b1
commit 69ab47edc8
7 changed files with 265 additions and 461 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
{
"author": "OpenVidu",
"dependencies": {
"@types/node": "12.12.14",
"@types/node": "13.7.1",
"@types/platform": "1.3.2",
"freeice": "2.2.2",
"hark": "1.2.3",
"platform": "1.3.5",
"uuid": "3.3.3",
"wolfy87-eventemitter": "5.2.8"
"uuid": "3.4.0",
"wolfy87-eventemitter": "5.2.9"
},
"description": "OpenVidu Browser",
"devDependencies": {
@ -22,10 +22,10 @@
"grunt-string-replace": "1.3.1",
"grunt-ts": "6.0.0-beta.22",
"tsify": "4.0.1",
"tslint": "5.20.1",
"typedoc": "0.15.3",
"typescript": "3.7.2",
"uglify-js": "3.7.1"
"tslint": "6.0.0",
"typedoc": "0.16.10",
"typescript": "3.7.5",
"uglify-js": "3.8.0"
},
"license": "Apache-2.0",
"main": "lib/index.js",

View File

@ -29,9 +29,19 @@ import { VideoInsertMode } from '../OpenViduInternal/Enums/VideoInsertMode';
import * as screenSharingAuto from '../OpenViduInternal/ScreenSharing/Screen-Capturing-Auto';
import * as screenSharing from '../OpenViduInternal/ScreenSharing/Screen-Capturing';
/**
* @hidden
*/
import EventEmitter = require('wolfy87-eventemitter');
/**
* @hidden
*/
import RpcBuilder = require('../OpenViduInternal/KurentoUtils/kurento-jsonrpc');
/**
* @hidden
*/
import platform = require('platform');
platform['isIonicIos'] = (platform.product === 'iPhone' || platform.product === 'iPad') && platform.ua!!.indexOf('Safari') === -1;
platform['isIonicAndroid'] = platform.os!!.family === 'Android' && platform.name == "Android Browser";
@ -802,7 +812,6 @@ export class OpenVidu {
sendCloseMessage: false,
ws: {
uri: this.wsUri,
useSockJS: false,
onconnected: onConnectSucces,
ondisconnect: this.disconnectCallback.bind(this),
onreconnecting: this.reconnectingCallback.bind(this),

View File

@ -31,8 +31,11 @@ import { StreamManagerEvent } from '../OpenViduInternal/Events/StreamManagerEven
import { StreamPropertyChangedEvent } from '../OpenViduInternal/Events/StreamPropertyChangedEvent';
import { OpenViduError, OpenViduErrorName } from '../OpenViduInternal/Enums/OpenViduError';
import EventEmitter = require('wolfy87-eventemitter');
/**
* @hidden
*/
import hark = require('hark');
import EventEmitter = require('wolfy87-eventemitter');
import platform = require('platform');
@ -770,6 +773,10 @@ export class Stream implements EventDispatcher {
if (!this.getWebRtcPeer() || !this.getRTCPeerConnection()) {
return false;
}
if (this.isLocal && !!this.session.openvidu.advancedConfiguration.forceMediaReconnectionAfterNetworkDrop) {
console.warn('OpenVidu Browser advanced configuration option "forceMediaReconnectionAfterNetworkDrop" is enabled. Publisher stream ' + this.streamId + 'will force a reconnection');
return true;
}
const iceConnectionState: RTCIceConnectionState = this.getRTCPeerConnection().iceConnectionState;
return iceConnectionState === 'disconnected' || iceConnectionState === 'failed';
}

View File

@ -41,4 +41,15 @@ export interface OpenViduAdvancedConfiguration {
*/
publisherSpeakingEventsOptions?: any;
/**
* Determines the automatic reconnection process policy. Whenever the client's network drops, OpenVidu Browser starts a reconnection process with OpenVidu Server. After network is recovered, OpenVidu Browser automatically
* inspects all of its media streams to see their status. For any of them that are broken, it asks OpenVidu Server for a forced and silent reconnection.
*
* This policy is technically enough to recover any broken media connection after a network drop, but in practice it has been proven that OpenVidu Browser may think a media connection has properly recovered when in fact it has not.
* This is not a common case, and it only affects Publisher streams, but it may occur. This property allows **forcing OpenVidu Browser to reconnect all of its outgoing media streams** after a network drop regardless of their supposed status.
*
* Default to `false`.
*/
forceMediaReconnectionAfterNetworkDrop?: boolean;
}

View File

@ -37,7 +37,6 @@ var Logger = console;
* <pre>
* ws : {
* uri : URI to conntect to,
* useSockJS : true (use SockJS) / false (use WebSocket) by default,
* onconnected : callback method to invoke when connection is successful,
* ondisconnect : callback method to invoke when the connection is lost (max retries for reconnecting reached),
* onreconnecting : callback method to invoke when the client is reconnecting,

View File

@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@ -16,25 +16,8 @@
"use strict";
var BrowserWebSocket = global.WebSocket || global.MozWebSocket;
var Logger = console;
/**
* Get either the `WebSocket` or `MozWebSocket` globals
* in the browser or try to resolve WebSocket-compatible
* interface exposed by `ws` for Node-like environment.
*/
/*var WebSocket = BrowserWebSocket;
if (!WebSocket && typeof window === 'undefined') {
try {
WebSocket = require('ws');
} catch (e) { }
}*/
//var SockJS = require('sockjs-client');
var MAX_RETRIES = 2000; // Forever...
var RETRY_TIME_MS = 3000; // FIXME: Implement exponential wait times...
@ -45,61 +28,45 @@ var CLOSED = 3;
/*
config = {
uri : wsUri,
useSockJS : true (use SockJS) / false (use WebSocket) by default,
onconnected : callback method to invoke when connection is successful,
ondisconnect : callback method to invoke when the connection is lost (max retries for reconnecting reached),
onreconnecting : callback method to invoke when the client is reconnecting,
onreconnected : callback method to invoke when the client successfully reconnects,
};
uri : wsUri,
onconnected : callback method to invoke when connection is successful,
ondisconnect : callback method to invoke when the connection is lost (max retries for reconnecting reached),
onreconnecting : callback method to invoke when the client is reconnecting,
onreconnected : callback method to invoke when the client successfully reconnects,
};
*/
function WebSocketWithReconnection(config) {
var closing = false;
var registerMessageHandler;
var wsUri = config.uri;
var useSockJS = config.useSockJS;
var reconnecting = false;
var forcingDisconnection = false;
var ws = new WebSocket(wsUri);
var ws;
if (useSockJS) {
ws = new SockJS(wsUri);
} else {
ws = new WebSocket(wsUri);
}
ws.onopen = function () {
logConnected(ws, wsUri);
ws.onopen = () => {
Logger.debug("WebSocket connected to " + wsUri);
if (config.onconnected) {
config.onconnected();
}
};
ws.onerror = function (error) {
Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error);
ws.onerror = error => {
Logger.error(
"Could not connect to " + wsUri + " (invoking onerror if defined)",
error
);
if (config.onerror) {
config.onerror(error);
}
};
function logConnected(ws, wsUri) {
try {
Logger.debug("WebSocket connected to " + wsUri);
} catch (e) {
Logger.error(e);
}
}
var reconnectionOnClose = function () {
var reconnectionOnClose = () => {
if (ws.readyState === CLOSED) {
if (closing) {
Logger.debug("Connection closed by user");
} else {
Logger.debug("Connection closed unexpectecly. Reconnecting...");
reconnectToSameUri(MAX_RETRIES, 1);
reconnect(MAX_RETRIES, 1);
}
} else {
Logger.debug("Close callback from previous websocket. Ignoring it");
@ -108,133 +75,75 @@ function WebSocketWithReconnection(config) {
ws.onclose = reconnectionOnClose;
function reconnectToSameUri(maxRetries, numRetries) {
Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")");
function reconnect(maxRetries, numRetries) {
Logger.debug(
"reconnect (attempt #" + numRetries + ", max=" + maxRetries + ")"
);
if (numRetries === 1) {
if (reconnecting) {
Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection.")
Logger.warn(
"Trying to reconnect when already reconnecting... Ignoring this reconnection."
);
return;
} else {
reconnecting = true;
}
if (config.onreconnecting) {
config.onreconnecting();
}
}
if (forcingDisconnection) {
reconnectToNewUri(maxRetries, numRetries, wsUri);
} else {
if (config.newWsUriOnReconnection) {
config.newWsUriOnReconnection(function (error, newWsUri) {
if (error) {
Logger.debug(error);
setTimeout(function () {
reconnectToSameUri(maxRetries, numRetries + 1);
}, RETRY_TIME_MS);
} else {
reconnectToNewUri(maxRetries, numRetries, newWsUri);
}
})
} else {
reconnectToNewUri(maxRetries, numRetries, wsUri);
}
}
reconnectAux(maxRetries, numRetries);
}
// TODO Test retries. How to force not connection?
function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) {
function reconnectAux(maxRetries, numRetries) {
Logger.debug("Reconnection attempt #" + numRetries);
ws.close();
ws = new WebSocket(wsUri);
wsUri = reconnectWsUri || wsUri;
var newWs;
if (useSockJS) {
newWs = new SockJS(wsUri);
} else {
newWs = new WebSocket(wsUri);
}
newWs.onopen = function () {
Logger.debug("Reconnected after " + numRetries + " attempts...");
logConnected(newWs, wsUri);
ws.onopen = () => {
Logger.debug(
"Reconnected to " + wsUri + " after " + numRetries + " attempts..."
);
reconnecting = false;
registerMessageHandler();
if (config.onreconnected()) {
config.onreconnected();
}
newWs.onclose = reconnectionOnClose;
ws.onclose = reconnectionOnClose;
};
var onErrorOrClose = function (error) {
ws.onerror = error => {
Logger.warn("Reconnection error: ", error);
if (numRetries === maxRetries) {
if (config.ondisconnect) {
config.ondisconnect();
}
} else {
setTimeout(function () {
reconnectToSameUri(maxRetries, numRetries + 1);
setTimeout(() => {
reconnect(maxRetries, numRetries + 1);
}, RETRY_TIME_MS);
}
};
newWs.onerror = onErrorOrClose;
ws = newWs;
}
this.close = function () {
this.close = () => {
closing = true;
ws.close();
};
// This method is only for testing
this.forceClose = function (millis) {
Logger.debug("Testing: Force WebSocket close");
if (millis) {
Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure");
var goodWsUri = wsUri;
wsUri = "wss://21.234.12.34.4:443/";
forcingDisconnection = true;
setTimeout(function () {
Logger.debug("Testing: Recover good wsUri " + goodWsUri);
wsUri = goodWsUri;
forcingDisconnection = false;
}, millis);
}
ws.close();
};
this.reconnectWs = function () {
this.reconnectWs = () => {
Logger.debug("reconnectWs");
reconnectToSameUri(MAX_RETRIES, 1);
reconnect(MAX_RETRIES, 1);
};
this.send = function (message) {
this.send = message => {
ws.send(message);
};
this.addEventListener = function (type, callback) {
registerMessageHandler = function () {
this.addEventListener = (type, callback) => {
registerMessageHandler = () => {
ws.addEventListener(type, callback);
};
registerMessageHandler();
};
}