Implementing connection recovery via a web client (#4, #5) (#6)

- update webSocketWithReconnect js
- update jsonrpcclient js
- update Openvidu ts
- update Session ts
- add RPC ID to Connection ts
pull/173/head
Kai Ren 2018-12-20 09:03:47 +02:00 committed by Konstantin
parent 6fd40f4f7d
commit 0e670bd107
24 changed files with 525 additions and 533 deletions

View File

@ -12,6 +12,10 @@ export declare class Connection {
* Unique identifier of the connection * Unique identifier of the connection
*/ */
connectionId: string; connectionId: string;
/**
* RPC session ID.
*/
rpcSessionId: string;
/** /**
* Time when this connection was created (UTC milliseconds) * Time when this connection was created (UTC milliseconds)
*/ */

View File

@ -1 +1 @@
{"version":3,"file":"Connection.js","sourceRoot":"","sources":["../../src/OpenVidu/Connection.ts"],"names":[],"mappings":"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"} {"version":3,"file":"Connection.js","sourceRoot":"","sources":["../../src/OpenVidu/Connection.ts"],"names":[],"mappings":"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"}

View File

@ -137,6 +137,7 @@ export declare class OpenVidu {
* - `publisherSpeakingEventsOptions`: custom configuration for the [[PublisherSpeakingEvent]] feature * - `publisherSpeakingEventsOptions`: custom configuration for the [[PublisherSpeakingEvent]] feature
*/ */
setAdvancedConfiguration(configuration: OpenViduAdvancedConfiguration): void; setAdvancedConfiguration(configuration: OpenViduAdvancedConfiguration): void;
reconnect(): void;
/** /**
* @hidden * @hidden
*/ */

View File

@ -377,6 +377,11 @@ var OpenVidu = /** @class */ (function () {
OpenVidu.prototype.setAdvancedConfiguration = function (configuration) { OpenVidu.prototype.setAdvancedConfiguration = function (configuration) {
this.advancedConfiguration = configuration; this.advancedConfiguration = configuration;
}; };
// Only for testing.
OpenVidu.prototype.reconnect = function () {
console.log("Attempt to test reconnect");
this.jsonRpcClient.forceClose();
};
/* Hidden methods */ /* Hidden methods */
/** /**
* @hidden * @hidden
@ -549,7 +554,7 @@ var OpenVidu = /** @class */ (function () {
* @hidden * @hidden
*/ */
OpenVidu.prototype.closeWs = function () { OpenVidu.prototype.closeWs = function () {
this.jsonRpcClient.close(); this.jsonRpcClient.close(4102, "Connection closed by client");
}; };
/** /**
* @hidden * @hidden
@ -584,7 +589,7 @@ var OpenVidu = /** @class */ (function () {
OpenVidu.prototype.disconnectCallback = function () { OpenVidu.prototype.disconnectCallback = function () {
console.warn('Websocket connection lost'); console.warn('Websocket connection lost');
if (this.isRoomAvailable()) { if (this.isRoomAvailable()) {
this.session.onLostConnection(); this.session.onLostConnection('Websocket connection lost');
} }
else { else {
alert('Connection error. Please reload page.'); alert('Connection error. Please reload page.');
@ -592,17 +597,24 @@ var OpenVidu = /** @class */ (function () {
}; };
OpenVidu.prototype.reconnectingCallback = function () { OpenVidu.prototype.reconnectingCallback = function () {
console.warn('Websocket connection lost (reconnecting)'); console.warn('Websocket connection lost (reconnecting)');
if (this.isRoomAvailable()) { if (!this.isRoomAvailable()) {
this.session.onLostConnection();
}
else {
alert('Connection error. Please reload page.'); alert('Connection error. Please reload page.');
} }
}; };
OpenVidu.prototype.reconnectedCallback = function () { OpenVidu.prototype.reconnectedCallback = function () {
var _this = this;
console.warn('Websocket reconnected'); console.warn('Websocket reconnected');
if (this.isRoomAvailable()) { if (this.isRoomAvailable()) {
this.session.onRecoveredConnection(); this.sendRequest("connect", { sessionId: this.session.connection.rpcSessionId }, function (error, response) {
if (error != null) {
console.error(error);
_this.session.onLostConnection("Reconnection fault");
_this.jsonRpcClient.close(4101, "Reconnection fault");
return;
}
_this.jsonRpcClient.resetPing();
_this.session.onRecoveredConnection();
});
} }
else { else {
alert('Connection error. Please reload page.'); alert('Connection error. Please reload page.');

File diff suppressed because one or more lines are too long

View File

@ -254,7 +254,7 @@ export declare class Session implements EventDispatcher {
/** /**
* @hidden * @hidden
*/ */
onLostConnection(): void; onLostConnection(reason: any): void;
/** /**
* @hidden * @hidden
*/ */

View File

@ -771,20 +771,10 @@ var Session = /** @class */ (function () {
/** /**
* @hidden * @hidden
*/ */
Session.prototype.onLostConnection = function () { Session.prototype.onLostConnection = function (reason) {
/*if (!this.connection) { console.warn('Lost connection in Session # waiting for reconnect', this.sessionId);
console.warn('Not connected to session: if you are not debugging, this is probably a certificate error');
const url = 'https://' + this.openvidu.getWsUri().split('wss://')[1].split('/openvidu')[0];
if (window.confirm('If you are not debugging, this is probably a certificate error at \"' + url + '\"\n\nClick OK to navigate and accept it')) {
location.assign(url + '/accept-certificate');
}
return;
}*/
console.warn('Lost connection in Session ' + this.sessionId);
if (!!this.sessionId && !this.connection.disposed) { if (!!this.sessionId && !this.connection.disposed) {
this.leave(true, 'networkDisconnect'); this.leave(true, reason);
} }
}; };
/** /**
@ -905,6 +895,7 @@ var Session = /** @class */ (function () {
_this.connection = new Connection_1.Connection(_this); _this.connection = new Connection_1.Connection(_this);
_this.connection.connectionId = response.id; _this.connection.connectionId = response.id;
_this.connection.data = response.metadata; _this.connection.data = response.metadata;
_this.connection.rpcSessionId = response.sessionId;
// Initialize remote Connections with value returned by openvidu-server // Initialize remote Connections with value returned by openvidu-server
var events_1 = { var events_1 = {
connections: new Array(), connections: new Array(),

File diff suppressed because one or more lines are too long

View File

@ -30,6 +30,11 @@ function JsonRpcClient(configuration) {
Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it"); Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it");
return; return;
} }
clearInterval(pingInterval);
pingPongStarted = false;
enabledPings = false;
pingNextNum = -1;
rpc.cancel();
status = RECONNECTING; status = RECONNECTING;
if (onreconnecting) { if (onreconnecting) {
onreconnecting(); onreconnecting();
@ -42,9 +47,7 @@ function JsonRpcClient(configuration) {
return; return;
} }
status = CONNECTED; status = CONNECTED;
enabledPings = true;
updateNotReconnectIfLessThan(); updateNotReconnectIfLessThan();
usePing();
if (onreconnected) { if (onreconnected) {
onreconnected(); onreconnected();
} }
@ -65,6 +68,11 @@ function JsonRpcClient(configuration) {
wsConfig.onerror = function (error) { wsConfig.onerror = function (error) {
Logger.debug("--------- ONERROR -----------"); Logger.debug("--------- ONERROR -----------");
status = DISCONNECTED; status = DISCONNECTED;
clearInterval(pingInterval);
pingPongStarted = false;
enabledPings = false;
pingNextNum = -1;
rpc.cancel();
if (onerror) { if (onerror) {
onerror(error); onerror(error);
} }
@ -161,8 +169,8 @@ function JsonRpcClient(configuration) {
} }
} }
} }
this.close = function () { this.close = function (code, reason) {
Logger.debug("Closing jsonRpcClient explicitly by client"); Logger.debug("Closing with code: " + code + " because: " + reason);
if (pingInterval != undefined) { if (pingInterval != undefined) {
Logger.debug("Clearing ping interval"); Logger.debug("Clearing ping interval");
clearInterval(pingInterval); clearInterval(pingInterval);
@ -175,11 +183,11 @@ function JsonRpcClient(configuration) {
if (error) { if (error) {
Logger.error("Error sending close message: " + JSON.stringify(error)); Logger.error("Error sending close message: " + JSON.stringify(error));
} }
ws.close(); ws.close(code, reason);
}); });
} }
else { else {
ws.close(); ws.close(code, reason);
} }
}; };
this.forceClose = function (millis) { this.forceClose = function (millis) {
@ -188,6 +196,11 @@ function JsonRpcClient(configuration) {
this.reconnect = function () { this.reconnect = function () {
ws.reconnectWs(); ws.reconnectWs();
}; };
this.resetPing = function () {
enabledPings = true;
pingNextNum = 0;
usePing();
};
} }
module.exports = JsonRpcClient; module.exports = JsonRpcClient;
//# sourceMappingURL=jsonrpcclient.js.map //# sourceMappingURL=jsonrpcclient.js.map

View File

@ -1,156 +1,106 @@
"use strict"; "use strict";
var BrowserWebSocket = global.WebSocket || global.MozWebSocket;
var Logger = console; var Logger = console;
var MAX_RETRIES = 2000; var MAX_RETRY_TIME_MS = 10000;
var RETRY_TIME_MS = 3000;
var CONNECTING = 0; var CONNECTING = 0;
var OPEN = 1; var OPEN = 1;
var CLOSING = 2; var CLOSING = 2;
var CLOSED = 3; var CLOSED = 3;
function WebSocketWithReconnection(config) { function WebSocketWithReconnection(config) {
var closing = false; var totalNumRetries = 1;
var registerMessageHandler; var registerMessageHandler;
var wsUri = config.uri;
var useSockJS = config.useSockJS;
var reconnecting = false; var reconnecting = false;
var forcingDisconnection = false;
var ws; var ws;
if (useSockJS) { function onOpen() {
ws = new SockJS(wsUri); ws.addEventListener("close", onClose);
} if (reconnecting === true) {
else {
ws = new WebSocket(wsUri);
}
ws.onopen = function () {
logConnected(ws, wsUri);
if (config.onconnected) {
config.onconnected();
}
};
ws.onerror = function (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 () {
if (ws.readyState === CLOSED) {
if (closing) {
Logger.debug("Connection closed by user");
}
else {
Logger.debug("Connection closed unexpectecly. Reconnecting...");
reconnectToSameUri(MAX_RETRIES, 1);
}
}
else {
Logger.debug("Close callback from previous websocket. Ignoring it");
}
};
ws.onclose = reconnectionOnClose;
function reconnectToSameUri(maxRetries, numRetries) {
Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")");
if (numRetries === 1) {
if (reconnecting) {
Logger.warn("Trying to reconnectToNewUri when 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);
}
}
}
function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) {
Logger.debug("Reconnection attempt #" + numRetries);
ws.close();
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);
reconnecting = false;
registerMessageHandler(); registerMessageHandler();
if (config.onreconnected()) { if (config.onreconnected) {
config.onreconnected(); config.onreconnected();
} }
newWs.onclose = reconnectionOnClose; reconnecting = false;
}; }
var onErrorOrClose = function (error) { else {
Logger.warn("Reconnection error: ", error); if (config.onconnected) {
if (numRetries === maxRetries) { config.onconnected();
if (config.ondisconnect) {
config.ondisconnect();
}
} }
else { }
setTimeout(function () { totalNumRetries = 1;
reconnectToSameUri(maxRetries, numRetries + 1);
}, RETRY_TIME_MS);
}
};
newWs.onerror = onErrorOrClose;
ws = newWs;
} }
this.close = function () { function onClose(event) {
closing = true; removeAllListeners();
ws.close(); Logger.log("Close Web Socket code: " + event.code + " reason: " + event.reason);
if (event.code > 4000) {
if (config.onerror) {
config.onerror(event.reason);
}
return;
}
if (reconnecting === false) {
reconnecting = true;
reconnect(500 * totalNumRetries);
}
}
function onError(event) {
removeAllListeners();
if (config.onerror) {
config.onerror("Web socket establishing error");
}
reconnect(500 * totalNumRetries);
}
function resetWebSocket(config) {
var newWS;
if (config.useSockJS) {
newWS = new SockJS(config.uri);
}
else {
newWS = new WebSocket(config.uri);
}
newWS.addEventListener("open", onOpen);
newWS.addEventListener("error", onError);
return newWS;
}
function removeAllListeners() {
ws.removeEventListener("open", onOpen);
ws.removeEventListener("error", onError);
ws.removeEventListener("close", onClose);
}
function reconnect(reconnectInterval) {
if (reconnectInterval > MAX_RETRY_TIME_MS) {
if (config.onerror) {
config.onerror("Server is not responding");
}
return;
}
if (config.onreconnecting) {
config.onreconnecting();
}
setTimeout(function () {
totalNumRetries++;
ws = resetWebSocket(config);
}, reconnectInterval);
}
ws = resetWebSocket(config);
this.close = function (code, reason) {
if (ws.readyState < CLOSING) {
ws.close(code, reason);
}
}; };
this.forceClose = function (millis) { this.forceClose = function (millis) {
Logger.debug("Testing: Force WebSocket close"); Logger.debug("Testing: Force WebSocket close");
if (millis) { if (millis) {
Logger.debug("Testing: Change wsUri for " + millis + " millis to simulate net failure"); Logger.log("Testing: Change wsUri for " + millis
var goodWsUri = wsUri; + " millis to simulate net failure");
wsUri = "wss://21.234.12.34.4:443/";
forcingDisconnection = true;
setTimeout(function () { setTimeout(function () {
Logger.debug("Testing: Recover good wsUri " + goodWsUri); ws.close(1000, "Test close for reconnect with timeout");
wsUri = goodWsUri;
forcingDisconnection = false;
}, millis); }, millis);
} }
ws.close(); else {
ws.close(1000, "Test close for reconnect");
}
}; };
this.reconnectWs = function () { this.reconnectWs = function () {
Logger.debug("reconnectWs"); Logger.log("reconnectWs");
reconnectToSameUri(MAX_RETRIES, 1); ws.close(1000, "Close Web socket for reconnection");
}; };
this.send = function (message) { this.send = function (message) {
ws.send(message); ws.send(message);

View File

@ -1 +1 @@
{"version":3,"file":"webSocketWithReconnection.js","sourceRoot":"","sources":["../../../../../../src/OpenViduInternal/KurentoUtils/kurento-jsonrpc/clients/transports/webSocketWithReconnection.js"],"names":[],"mappings":"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"} {"version":3,"file":"webSocketWithReconnection.js","sourceRoot":"","sources":["../../../../../../src/OpenViduInternal/KurentoUtils/kurento-jsonrpc/clients/transports/webSocketWithReconnection.js"],"names":[],"mappings":"AAgBA,YAAY,CAAC;AAMb,IAAI,MAAM,GAAG,OAAO,CAAC;AAOrB,IAAI,iBAAiB,GAAG,KAAK,CAAC;AAO9B,IAAI,UAAU,GAAG,CAAC,CAAC;AAOnB,IAAI,IAAI,GAAG,CAAC,CAAC;AAOb,IAAI,OAAO,GAAG,CAAC,CAAC;AAOhB,IAAI,MAAM,GAAG,CAAC,CAAC;AAef,SAAS,yBAAyB,CAAC,MAAM;IAOvC,IAAI,eAAe,GAAG,CAAC,CAAC;IAKxB,IAAI,sBAAsB,CAAC;IAO3B,IAAI,YAAY,GAAG,KAAK,CAAC;IAKzB,IAAI,EAAE,CAAC;IAKP,SAAS,MAAM;QACb,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtC,IAAI,YAAY,KAAK,IAAI,EAAE;YACzB,sBAAsB,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,aAAa,EAAE;gBACxB,MAAM,CAAC,aAAa,EAAE,CAAC;aACxB;YACD,YAAY,GAAG,KAAK,CAAC;SACtB;aAAM;YACL,IAAI,MAAM,CAAC,WAAW,EAAE;gBACtB,MAAM,CAAC,WAAW,EAAE,CAAC;aACtB;SACF;QACD,eAAe,GAAG,CAAC,CAAC;IACtB,CAAC;IAOD,SAAS,OAAO,CAAC,KAAK;QACpB,kBAAkB,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,CACR,yBAAyB,GAAG,KAAK,CAAC,IAAI,GAAG,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,KAAK,CAAC,IAAI,GAAG,IAAI,EAAE;YACrB,IAAI,MAAM,CAAC,OAAO,EAAE;gBAClB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;aAC9B;YACD,OAAO;SACR;QAED,IAAI,YAAY,KAAK,KAAK,EAAE;YAC1B,YAAY,GAAG,IAAI,CAAC;YACpB,SAAS,CAAC,GAAG,GAAG,eAAe,CAAC,CAAA;SACjC;IACH,CAAC;IAOD,SAAS,OAAO,CAAC,KAAK;QACpB,kBAAkB,EAAE,CAAC;QACrB,IAAI,MAAM,CAAC,OAAO,EAAE;YAClB,MAAM,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;SACjD;QACD,SAAS,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC;IACnC,CAAC;IASD,SAAS,cAAc,CAAC,MAAM;QAC5B,IAAI,KAAK,CAAC;QACV,IAAI,MAAM,CAAC,SAAS,EAAE;YACpB,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SAChC;aAAM;YACL,KAAK,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;SACnC;QAED,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,KAAK,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAKD,SAAS,kBAAkB;QACzB,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAOD,SAAS,SAAS,CAAC,iBAAiB;QAClC,IAAI,iBAAiB,GAAG,iBAAiB,EAAE;YACzC,IAAI,MAAM,CAAC,OAAO,EAAE;gBAClB,MAAM,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAA;aAC3C;YACD,OAAO;SACR;QACD,IAAI,MAAM,CAAC,cAAc,EAAE;YACzB,MAAM,CAAC,cAAc,EAAE,CAAC;SACzB;QACD,UAAU,CAAC;YACT,eAAe,EAAE,CAAC;YAClB,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;QAE9B,CAAC,EAAE,iBAAiB,CAAC,CAAA;IACvB,CAAC;IAGD,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAK5B,IAAI,CAAC,KAAK,GAAG,UAAU,IAAI,EAAE,MAAM;QACjC,IAAI,EAAE,CAAC,UAAU,GAAG,OAAO,EAAE;YAC3B,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;SACxB;IACH,CAAC,CAAC;IAOF,IAAI,CAAC,UAAU,GAAG,UAAU,MAAM;QAChC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAE/C,IAAI,MAAM,EAAE;YACV,MAAM,CAAC,GAAG,CAAC,4BAA4B,GAAG,MAAM;kBAC5C,iCAAiC,CAAC,CAAC;YACvC,UAAU,CAAC;gBACT,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,uCAAuC,CAAC,CAAC;YAE1D,CAAC,EAAE,MAAM,CAAC,CAAC;SACZ;aAAM;YACL,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;SAC5C;IAEH,CAAC,CAAC;IAKF,IAAI,CAAC,WAAW,GAAG;QACjB,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC1B,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,mCAAmC,CAAC,CAAA;IACrD,CAAC,CAAC;IAOF,IAAI,CAAC,IAAI,GAAG,UAAU,OAAO;QAC3B,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC,CAAC;IAQF,IAAI,CAAC,gBAAgB,GAAG,UAAU,IAAI,EAAE,QAAQ;QAC9C,sBAAsB,GAAG;YACvB,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,sBAAsB,EAAE,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,OAAO,GAAG,yBAAyB,CAAC"}

View File

@ -290,7 +290,7 @@ function RpcBuilder(packer, options, transport, onRequest) {
this.close = function () { this.close = function () {
var transport = this.getTransport(); var transport = this.getTransport();
if (transport && transport.close) if (transport && transport.close)
transport.close(); transport.close(4003, "Cancel request");
this.cancel(); this.cancel();
processedResponses.forEach(clearTimeout); processedResponses.forEach(clearTimeout);
responses.forEach(function (response) { responses.forEach(function (response) {

File diff suppressed because one or more lines are too long

View File

@ -33,6 +33,11 @@ export class Connection {
*/ */
connectionId: string; connectionId: string;
/**
* RPC session ID.
*/
rpcSessionId: string;
/** /**
* Time when this connection was created (UTC milliseconds) * Time when this connection was created (UTC milliseconds)
*/ */
@ -164,5 +169,4 @@ export class Connection {
} }
this.disposed = true; this.disposed = true;
} }
} }

View File

@ -456,6 +456,12 @@ export class OpenVidu {
this.advancedConfiguration = configuration; this.advancedConfiguration = configuration;
} }
// Only for testing.
reconnect():void{
console.log("Attempt to test reconnect");
this.jsonRpcClient.forceClose();
}
/* Hidden methods */ /* Hidden methods */
@ -636,7 +642,7 @@ export class OpenVidu {
* @hidden * @hidden
*/ */
closeWs(): void { closeWs(): void {
this.jsonRpcClient.close(); this.jsonRpcClient.close(4102, "Connection closed by client");
} }
/** /**
@ -678,7 +684,7 @@ export class OpenVidu {
private disconnectCallback(): void { private disconnectCallback(): void {
console.warn('Websocket connection lost'); console.warn('Websocket connection lost');
if (this.isRoomAvailable()) { if (this.isRoomAvailable()) {
this.session.onLostConnection(); this.session.onLostConnection('Websocket connection lost');
} else { } else {
alert('Connection error. Please reload page.'); alert('Connection error. Please reload page.');
} }
@ -686,9 +692,7 @@ export class OpenVidu {
private reconnectingCallback(): void { private reconnectingCallback(): void {
console.warn('Websocket connection lost (reconnecting)'); console.warn('Websocket connection lost (reconnecting)');
if (this.isRoomAvailable()) { if (!this.isRoomAvailable()) {
this.session.onLostConnection();
} else {
alert('Connection error. Please reload page.'); alert('Connection error. Please reload page.');
} }
} }
@ -696,7 +700,16 @@ export class OpenVidu {
private reconnectedCallback(): void { private reconnectedCallback(): void {
console.warn('Websocket reconnected'); console.warn('Websocket reconnected');
if (this.isRoomAvailable()) { if (this.isRoomAvailable()) {
this.session.onRecoveredConnection(); this.sendRequest("connect", {sessionId: this.session.connection.rpcSessionId}, (error, response)=> {
if(error != null){
console.error(error);
this.session.onLostConnection("Reconnection fault");
this.jsonRpcClient.close(4101, "Reconnection fault");
return;
}
this.jsonRpcClient.resetPing();
this.session.onRecoveredConnection();
})
} else { } else {
alert('Connection error. Please reload page.'); alert('Connection error. Please reload page.');
} }

View File

@ -899,22 +899,10 @@ export class Session implements EventDispatcher {
/** /**
* @hidden * @hidden
*/ */
onLostConnection(): void { onLostConnection(reason): void {
console.warn('Lost connection in Session # waiting for reconnect', this.sessionId);
/*if (!this.connection) {
console.warn('Not connected to session: if you are not debugging, this is probably a certificate error');
const url = 'https://' + this.openvidu.getWsUri().split('wss://')[1].split('/openvidu')[0];
if (window.confirm('If you are not debugging, this is probably a certificate error at \"' + url + '\"\n\nClick OK to navigate and accept it')) {
location.assign(url + '/accept-certificate');
}
return;
}*/
console.warn('Lost connection in Session ' + this.sessionId);
if (!!this.sessionId && !this.connection.disposed) { if (!!this.sessionId && !this.connection.disposed) {
this.leave(true, 'networkDisconnect'); this.leave(true, reason);
} }
} }
@ -1047,6 +1035,7 @@ export class Session implements EventDispatcher {
this.connection = new Connection(this); this.connection = new Connection(this);
this.connection.connectionId = response.id; this.connection.connectionId = response.id;
this.connection.data = response.metadata; this.connection.data = response.metadata;
this.connection.rpcSessionId = response.sessionId;
// Initialize remote Connections with value returned by openvidu-server // Initialize remote Connections with value returned by openvidu-server
const events = { const events = {

View File

@ -82,6 +82,12 @@ function JsonRpcClient(configuration) {
return; return;
} }
clearInterval(pingInterval);
pingPongStarted = false;
enabledPings = false;
pingNextNum = -1;
rpc.cancel();
status = RECONNECTING; status = RECONNECTING;
if (onreconnecting) { if (onreconnecting) {
onreconnecting(); onreconnecting();
@ -96,14 +102,12 @@ function JsonRpcClient(configuration) {
} }
status = CONNECTED; status = CONNECTED;
enabledPings = true; updateNotReconnectIfLessThan();
updateNotReconnectIfLessThan();
usePing();
if (onreconnected) { if (onreconnected) {
onreconnected(); onreconnected();
}
} }
};
wsConfig.onconnected = function() { wsConfig.onconnected = function() {
Logger.debug("--------- ONCONNECTED -----------"); Logger.debug("--------- ONCONNECTED -----------");
@ -126,6 +130,12 @@ function JsonRpcClient(configuration) {
status = DISCONNECTED; status = DISCONNECTED;
clearInterval(pingInterval);
pingPongStarted = false;
enabledPings = false;
pingNextNum = -1;
rpc.cancel();
if (onerror) { if (onerror) {
onerror(error); onerror(error);
} }
@ -239,8 +249,8 @@ function JsonRpcClient(configuration) {
} }
} }
this.close = function() { this.close = function(code, reason) {
Logger.debug("Closing jsonRpcClient explicitly by client"); Logger.debug("Closing with code: "+code+ " because: "+reason);
if (pingInterval != undefined) { if (pingInterval != undefined) {
Logger.debug("Clearing ping interval"); Logger.debug("Clearing ping interval");
@ -255,10 +265,10 @@ function JsonRpcClient(configuration) {
if (error) { if (error) {
Logger.error("Error sending close message: " + JSON.stringify(error)); Logger.error("Error sending close message: " + JSON.stringify(error));
} }
ws.close(); ws.close(code, reason);
}); });
} else { } else {
ws.close(); ws.close(code, reason);
} }
} }
@ -270,6 +280,12 @@ function JsonRpcClient(configuration) {
this.reconnect = function() { this.reconnect = function() {
ws.reconnectWs(); ws.reconnectWs();
} }
this.resetPing = function(){
enabledPings = true;
pingNextNum = 0;
usePing();
}
} }

View File

@ -15,36 +15,53 @@
*/ */
"use strict"; "use strict";
/**
var BrowserWebSocket = global.WebSocket || global.MozWebSocket; * GLOBAL VARIABLES:
*
* Logger function.
*/
var Logger = console; var Logger = console;
/** /**
* Get either the `WebSocket` or `MozWebSocket` globals * Max reconnect timeout.
* in the browser or try to resolve WebSocket-compatible *
* interface exposed by `ws` for Node-like environment. * @type {number} max reconnect timeout.
*/ */
var MAX_RETRY_TIME_MS = 10000;
/*var WebSocket = BrowserWebSocket; /**
if (!WebSocket && typeof window === 'undefined') { * Web socket ready state connecting.
try { *
WebSocket = require('ws'); * @type {number} connecting state.
} catch (e) { } */
}*/
//var SockJS = require('sockjs-client');
var MAX_RETRIES = 2000; // Forever...
var RETRY_TIME_MS = 3000; // FIXME: Implement exponential wait times...
var CONNECTING = 0; var CONNECTING = 0;
/**
* Web socket ready state open.
*
* @type {number} open state.
*/
var OPEN = 1; var OPEN = 1;
/**
* Web socket ready state closing.
*
* @type {number} closing state.
*/
var CLOSING = 2; var CLOSING = 2;
/**
* Web socket ready state closed.
*
* @type {number} closed state.
*/
var CLOSED = 3; var CLOSED = 3;
/* /**
config = { *
* Web socket decorator with reconnection.
*
config = {
uri : wsUri, uri : wsUri,
useSockJS : true (use SockJS) / false (use WebSocket) by default, useSockJS : true (use SockJS) / false (use WebSocket) by default,
onconnected : callback method to invoke when connection is successful, onconnected : callback method to invoke when connection is successful,
@ -52,191 +69,201 @@ config = {
onreconnecting : callback method to invoke when the client is reconnecting, onreconnecting : callback method to invoke when the client is reconnecting,
onreconnected : callback method to invoke when the client successfully reconnects, onreconnected : callback method to invoke when the client successfully reconnects,
}; };
*/ */
function WebSocketWithReconnection(config) { function WebSocketWithReconnection(config) {
var closing = false; /**
var registerMessageHandler; * Num of total retries.
var wsUri = config.uri; *
var useSockJS = config.useSockJS; * @type {number}
var reconnecting = false; */
var totalNumRetries = 1;
var forcingDisconnection = false; /**
* Register web socket message handler for registring message handler from RPC.
*/
var registerMessageHandler;
var ws; /**
* Web socket in reconnection process.
*
* @type {boolean} reconnection in progress if value is true.
*/
var reconnecting = false;
if (useSockJS) { /**
ws = new SockJS(wsUri); * Web socket instance.
*/
var ws;
/**
* Handles web socket open event.
*/
function onOpen() {
ws.addEventListener("close", onClose);
if (reconnecting === true) {
registerMessageHandler();
if (config.onreconnected) {
config.onreconnected();
}
reconnecting = false;
} else { } else {
ws = new WebSocket(wsUri); if (config.onconnected) {
config.onconnected();
}
}
totalNumRetries = 1;
}
/**
* Handles wWeb socket close event.
*
* @param event CloseEvent instance.
*/
function onClose(event) {
removeAllListeners();
Logger.log(
"Close Web Socket code: " + event.code + " reason: " + event.reason);
if (event.code > 4000) {
if (config.onerror) {
config.onerror(event.reason);
}
return;
} }
ws.onopen = function() { if (reconnecting === false) {
logConnected(ws, wsUri); reconnecting = true;
if (config.onconnected) { reconnect(500 * totalNumRetries)
config.onconnected(); }
} }
};
ws.onerror = function(error) { /**
Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); * Handles web socket error event.
if (config.onerror) { *
config.onerror(error); * @param event ErrorEvent instance.
} */
}; function onError(event) {
removeAllListeners();
if (config.onerror) {
config.onerror("Web socket establishing error");
}
reconnect(500 * totalNumRetries);
}
function logConnected(ws, wsUri) { /**
try { * Init new instance of Web socket.
Logger.debug("WebSocket connected to " + wsUri); *
} catch (e) { * @param config Web socket configuration.
Logger.error(e); *
} * @returns {WebSocket | SockJS} new web socket instance.
*/
function resetWebSocket(config) {
var newWS;
if (config.useSockJS) {
newWS = new SockJS(config.uri);
} else {
newWS = new WebSocket(config.uri);
} }
var reconnectionOnClose = function() { newWS.addEventListener("open", onOpen);
if (ws.readyState === CLOSED) { newWS.addEventListener("error", onError);
if (closing) { return newWS;
Logger.debug("Connection closed by user"); }
} else {
Logger.debug("Connection closed unexpectecly. Reconnecting...");
reconnectToSameUri(MAX_RETRIES, 1);
}
} else {
Logger.debug("Close callback from previous websocket. Ignoring it");
}
};
ws.onclose = reconnectionOnClose; /**
* Removes all Web socket event listeners.
*/
function removeAllListeners() {
ws.removeEventListener("open", onOpen);
ws.removeEventListener("error", onError);
ws.removeEventListener("close", onClose);
}
function reconnectToSameUri(maxRetries, numRetries) { /**
Logger.debug("reconnectToSameUri (attempt #" + numRetries + ", max=" + maxRetries + ")"); * Reconnects web socket with timeout.
*
* @param reconnectInterval reconnection timeout.
*/
function reconnect(reconnectInterval) {
if (reconnectInterval > MAX_RETRY_TIME_MS) {
if (config.onerror) {
config.onerror("Server is not responding")
}
return;
}
if (config.onreconnecting) {
config.onreconnecting();
}
setTimeout(function () {
totalNumRetries++;
ws = resetWebSocket(config);
if (numRetries === 1) { }, reconnectInterval)
if (reconnecting) { }
Logger.warn("Trying to reconnectToNewUri when reconnecting... Ignoring this reconnection.")
return;
} else {
reconnecting = true;
}
if (config.onreconnecting) { // init new web-socket instance.
config.onreconnecting(); ws = resetWebSocket(config);
}
}
if (forcingDisconnection) { /**
reconnectToNewUri(maxRetries, numRetries, wsUri); * Closes web-socket connection.
*/
this.close = function (code, reason) {
if (ws.readyState < CLOSING) {
ws.close(code, reason);
}
};
} else { /**
if (config.newWsUriOnReconnection) { * This method is only for testing. Simulate closing of web-socket connection.
config.newWsUriOnReconnection(function(error, newWsUri) { *
* @param millis timeout in millis
*/
this.forceClose = function (millis) {
Logger.debug("Testing: Force WebSocket close");
if (error) { if (millis) {
Logger.debug(error); Logger.log("Testing: Change wsUri for " + millis
setTimeout(function() { + " millis to simulate net failure");
reconnectToSameUri(maxRetries, numRetries + 1); setTimeout(function () {
}, RETRY_TIME_MS); ws.close(1000, "Test close for reconnect with timeout");
} else {
reconnectToNewUri(maxRetries, numRetries, newWsUri); }, millis);
} } else {
}) ws.close(1000, "Test close for reconnect");
} else {
reconnectToNewUri(maxRetries, numRetries, wsUri);
}
}
} }
// TODO Test retries. How to force not connection? };
function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) {
Logger.debug("Reconnection attempt #" + numRetries);
ws.close(); /**
* Closes web-socket for reconnection.
*/
this.reconnectWs = function () {
Logger.log("reconnectWs");
ws.close(1000, "Close Web socket for reconnection")
};
wsUri = reconnectWsUri || wsUri; /**
* Sends message within websocket.
*
* @param message some text message.
*/
this.send = function (message) {
ws.send(message);
};
var newWs; /**
if (useSockJS) { * Adds some event listener.
newWs = new SockJS(wsUri); *
} else { * @param type event type
newWs = new WebSocket(wsUri); * @param callback event callback.
} */
this.addEventListener = function (type, callback) {
newWs.onopen = function() { registerMessageHandler = function () {
Logger.debug("Reconnected after " + numRetries + " attempts..."); ws.addEventListener(type, callback);
logConnected(newWs, wsUri);
reconnecting = false;
registerMessageHandler();
if (config.onreconnected()) {
config.onreconnected();
}
newWs.onclose = reconnectionOnClose;
};
var onErrorOrClose = function(error) {
Logger.warn("Reconnection error: ", error);
if (numRetries === maxRetries) {
if (config.ondisconnect) {
config.ondisconnect();
}
} else {
setTimeout(function() {
reconnectToSameUri(maxRetries, numRetries + 1);
}, RETRY_TIME_MS);
}
};
newWs.onerror = onErrorOrClose;
ws = newWs;
}
this.close = function() {
closing = true;
ws.close();
}; };
registerMessageHandler();
// 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() {
Logger.debug("reconnectWs");
reconnectToSameUri(MAX_RETRIES, 1);
};
this.send = function(message) {
ws.send(message);
};
this.addEventListener = function(type, callback) {
registerMessageHandler = function() {
ws.addEventListener(type, callback);
};
registerMessageHandler();
};
} }
module.exports = WebSocketWithReconnection; module.exports = WebSocketWithReconnection;

View File

@ -519,7 +519,7 @@ function RpcBuilder(packer, options, transport, onRequest)
// Prevent to receive new messages // Prevent to receive new messages
var transport = this.getTransport(); var transport = this.getTransport();
if(transport && transport.close) if(transport && transport.close)
transport.close(); transport.close(4003, "Cancel request");
// Request & processed responses // Request & processed responses
this.cancel(); this.cancel();

View File

@ -223,7 +223,7 @@ export class WebRtcStats {
'exec': instrumentation.exec, 'exec': instrumentation.exec,
'component': instrumentation.component, 'component': instrumentation.component,
'stream': 'webRtc', 'stream': 'webRtc',
'type': metricId, 'et_type': metricId,
'stream_type': 'composed_metrics', 'stream_type': 'composed_metrics',
'units': units 'units': units
}; };
@ -263,7 +263,7 @@ export class WebRtcStats {
'exec': instrumentation.exec, 'exec': instrumentation.exec,
'component': instrumentation.component, 'component': instrumentation.component,
'stream': 'webRtc', 'stream': 'webRtc',
'type': metricId, 'et_type': metricId,
'stream_type': 'composed_metrics', 'stream_type': 'composed_metrics',
'units': units 'units': units
}; };
@ -317,7 +317,7 @@ export class WebRtcStats {
'exec': instrumentation.exec, 'exec': instrumentation.exec,
'component': instrumentation.component, 'component': instrumentation.component,
'stream': 'webRtc', 'stream': 'webRtc',
'type': metricId, 'et_type': metricId,
'stream_type': 'composed_metrics', 'stream_type': 'composed_metrics',
'units': units 'units': units
}; };
@ -351,7 +351,7 @@ export class WebRtcStats {
'exec': instrumentation.exec, 'exec': instrumentation.exec,
'component': instrumentation.component, 'component': instrumentation.component,
'stream': 'webRtc', 'stream': 'webRtc',
'type': metricId, 'et_type': metricId,
'stream_type': 'composed_metrics', 'stream_type': 'composed_metrics',
'units': units 'units': units
}; };

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long