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) {
registerMessageHandler();
if (config.onreconnected) {
config.onreconnected();
}
reconnecting = false;
} }
else { else {
ws = new WebSocket(wsUri);
}
ws.onopen = function () {
logConnected(ws, wsUri);
if (config.onconnected) { if (config.onconnected) {
config.onconnected(); config.onconnected();
} }
}; }
ws.onerror = function (error) { totalNumRetries = 1;
Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); }
function onClose(event) {
removeAllListeners();
Logger.log("Close Web Socket code: " + event.code + " reason: " + event.reason);
if (event.code > 4000) {
if (config.onerror) { if (config.onerror) {
config.onerror(error); config.onerror(event.reason);
} }
};
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; return;
} }
else { if (reconnecting === false) {
reconnecting = true; 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) { if (config.onreconnecting) {
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 () { setTimeout(function () {
reconnectToSameUri(maxRetries, numRetries + 1); totalNumRetries++;
}, RETRY_TIME_MS); ws = resetWebSocket(config);
}, reconnectInterval);
} }
else { ws = resetWebSocket(config);
reconnectToNewUri(maxRetries, numRetries, newWsUri); this.close = function (code, reason) {
if (ws.readyState < CLOSING) {
ws.close(code, reason);
} }
});
}
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();
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();
}; };
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":"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"}

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.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(); 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,35 +15,52 @@
*/ */
"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;
/* /**
*
* Web socket decorator with reconnection.
*
config = { config = {
uri : wsUri, uri : wsUri,
useSockJS : true (use SockJS) / false (use WebSocket) by default, useSockJS : true (use SockJS) / false (use WebSocket) by default,
@ -55,181 +72,191 @@ config = {
*/ */
function WebSocketWithReconnection(config) { function WebSocketWithReconnection(config) {
var closing = false; /**
* Num of total retries.
*
* @type {number}
*/
var totalNumRetries = 1;
/**
* Register web socket message handler for registring message handler from RPC.
*/
var registerMessageHandler; var registerMessageHandler;
var wsUri = config.uri;
var useSockJS = config.useSockJS; /**
* Web socket in reconnection process.
*
* @type {boolean} reconnection in progress if value is true.
*/
var reconnecting = false; var reconnecting = false;
var forcingDisconnection = false; /**
* Web socket instance.
*/
var ws; var ws;
if (useSockJS) { /**
ws = new SockJS(wsUri); * Handles web socket open event.
} else { */
ws = new WebSocket(wsUri); function onOpen() {
ws.addEventListener("close", onClose);
if (reconnecting === true) {
registerMessageHandler();
if (config.onreconnected) {
config.onreconnected();
} }
reconnecting = false;
ws.onopen = function() { } else {
logConnected(ws, wsUri);
if (config.onconnected) { if (config.onconnected) {
config.onconnected(); config.onconnected();
} }
}; }
totalNumRetries = 1;
}
ws.onerror = function(error) { /**
Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error); * 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) { if (config.onerror) {
config.onerror(error); config.onerror(event.reason);
} }
};
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; return;
} else {
reconnecting = true;
} }
if (reconnecting === false) {
reconnecting = true;
reconnect(500 * totalNumRetries)
}
}
/**
* Handles web socket error event.
*
* @param event ErrorEvent instance.
*/
function onError(event) {
removeAllListeners();
if (config.onerror) {
config.onerror("Web socket establishing error");
}
reconnect(500 * totalNumRetries);
}
/**
* Init new instance of Web socket.
*
* @param config Web socket configuration.
*
* @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);
}
newWS.addEventListener("open", onOpen);
newWS.addEventListener("error", onError);
return newWS;
}
/**
* Removes all Web socket event listeners.
*/
function removeAllListeners() {
ws.removeEventListener("open", onOpen);
ws.removeEventListener("error", onError);
ws.removeEventListener("close", onClose);
}
/**
* 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) { if (config.onreconnecting) {
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 () { setTimeout(function () {
reconnectToSameUri(maxRetries, numRetries + 1); totalNumRetries++;
}, RETRY_TIME_MS); ws = resetWebSocket(config);
} else {
reconnectToNewUri(maxRetries, numRetries, newWsUri); }, reconnectInterval)
}
})
} else {
reconnectToNewUri(maxRetries, numRetries, wsUri);
}
}
} }
// TODO Test retries. How to force not connection? // init new web-socket instance.
function reconnectToNewUri(maxRetries, numRetries, reconnectWsUri) { ws = resetWebSocket(config);
Logger.debug("Reconnection attempt #" + numRetries);
ws.close(); /**
* Closes web-socket connection.
wsUri = reconnectWsUri || wsUri; */
this.close = function (code, reason) {
var newWs; if (ws.readyState < CLOSING) {
if (useSockJS) { ws.close(code, reason);
newWs = new SockJS(wsUri);
} else {
newWs = new WebSocket(wsUri);
}
newWs.onopen = function() {
Logger.debug("Reconnected after " + numRetries + " attempts...");
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; /**
* This method is only for testing. Simulate closing of web-socket connection.
ws = newWs; *
} * @param millis timeout in millis
*/
this.close = function() {
closing = true;
ws.close();
};
// This method is only for testing
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);
} else {
ws.close(1000, "Test close for reconnect");
} }
ws.close();
}; };
/**
* Closes web-socket for reconnection.
*/
this.reconnectWs = function () { this.reconnectWs = function () {
Logger.debug("reconnectWs"); Logger.log("reconnectWs");
reconnectToSameUri(MAX_RETRIES, 1); ws.close(1000, "Close Web socket for reconnection")
}; };
/**
* Sends message within websocket.
*
* @param message some text message.
*/
this.send = function (message) { this.send = function (message) {
ws.send(message); ws.send(message);
}; };
/**
* Adds some event listener.
*
* @param type event type
* @param callback event callback.
*/
this.addEventListener = function (type, callback) { this.addEventListener = function (type, callback) {
registerMessageHandler = function () { registerMessageHandler = function () {
ws.addEventListener(type, callback); ws.addEventListener(type, callback);

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