2017-09-22 15:57:59 +02:00
|
|
|
/*
|
|
|
|
* (C) Copyright 2013-2015 Kurento (http://kurento.org/)
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
2020-02-19 09:35:10 +01:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2017-09-22 15:57:59 +02:00
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
var Logger = console;
|
|
|
|
|
|
|
|
var MAX_RETRIES = 2000; // Forever...
|
|
|
|
var RETRY_TIME_MS = 3000; // FIXME: Implement exponential wait times...
|
|
|
|
|
|
|
|
var CONNECTING = 0;
|
|
|
|
var OPEN = 1;
|
|
|
|
var CLOSING = 2;
|
|
|
|
var CLOSED = 3;
|
|
|
|
|
|
|
|
/*
|
|
|
|
config = {
|
2020-02-19 09:35:10 +01:00
|
|
|
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,
|
|
|
|
};
|
2017-09-22 15:57:59 +02:00
|
|
|
*/
|
|
|
|
function WebSocketWithReconnection(config) {
|
|
|
|
var closing = false;
|
|
|
|
var registerMessageHandler;
|
|
|
|
var wsUri = config.uri;
|
|
|
|
var reconnecting = false;
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
var ws = new WebSocket(wsUri);
|
2017-09-22 15:57:59 +02:00
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
ws.onopen = () => {
|
|
|
|
Logger.debug("WebSocket connected to " + wsUri);
|
2017-09-22 15:57:59 +02:00
|
|
|
if (config.onconnected) {
|
|
|
|
config.onconnected();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
ws.onerror = error => {
|
|
|
|
Logger.error(
|
|
|
|
"Could not connect to " + wsUri + " (invoking onerror if defined)",
|
|
|
|
error
|
|
|
|
);
|
2017-09-22 15:57:59 +02:00
|
|
|
if (config.onerror) {
|
|
|
|
config.onerror(error);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
var reconnectionOnClose = () => {
|
2017-09-22 15:57:59 +02:00
|
|
|
if (ws.readyState === CLOSED) {
|
|
|
|
if (closing) {
|
|
|
|
Logger.debug("Connection closed by user");
|
|
|
|
} else {
|
|
|
|
Logger.debug("Connection closed unexpectecly. Reconnecting...");
|
2020-02-19 09:35:10 +01:00
|
|
|
reconnect(MAX_RETRIES, 1);
|
2017-09-22 15:57:59 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Logger.debug("Close callback from previous websocket. Ignoring it");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
ws.onclose = reconnectionOnClose;
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
function reconnect(maxRetries, numRetries) {
|
|
|
|
Logger.debug(
|
|
|
|
"reconnect (attempt #" + numRetries + ", max=" + maxRetries + ")"
|
|
|
|
);
|
2017-09-22 15:57:59 +02:00
|
|
|
if (numRetries === 1) {
|
|
|
|
if (reconnecting) {
|
2020-02-19 09:35:10 +01:00
|
|
|
Logger.warn(
|
|
|
|
"Trying to reconnect when already reconnecting... Ignoring this reconnection."
|
|
|
|
);
|
2017-09-22 15:57:59 +02:00
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
reconnecting = true;
|
|
|
|
}
|
|
|
|
if (config.onreconnecting) {
|
|
|
|
config.onreconnecting();
|
|
|
|
}
|
|
|
|
}
|
2020-02-19 09:35:10 +01:00
|
|
|
reconnectAux(maxRetries, numRetries);
|
2017-09-22 15:57:59 +02:00
|
|
|
}
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
function reconnectAux(maxRetries, numRetries) {
|
2017-09-22 15:57:59 +02:00
|
|
|
Logger.debug("Reconnection attempt #" + numRetries);
|
|
|
|
ws.close();
|
2020-02-19 09:35:10 +01:00
|
|
|
ws = new WebSocket(wsUri);
|
2017-09-22 15:57:59 +02:00
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
ws.onopen = () => {
|
|
|
|
Logger.debug(
|
|
|
|
"Reconnected to " + wsUri + " after " + numRetries + " attempts..."
|
|
|
|
);
|
2017-09-22 15:57:59 +02:00
|
|
|
reconnecting = false;
|
|
|
|
registerMessageHandler();
|
|
|
|
if (config.onreconnected()) {
|
|
|
|
config.onreconnected();
|
|
|
|
}
|
2020-02-19 09:35:10 +01:00
|
|
|
ws.onclose = reconnectionOnClose;
|
2017-09-22 15:57:59 +02:00
|
|
|
};
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
ws.onerror = error => {
|
2017-09-22 15:57:59 +02:00
|
|
|
Logger.warn("Reconnection error: ", error);
|
|
|
|
if (numRetries === maxRetries) {
|
|
|
|
if (config.ondisconnect) {
|
|
|
|
config.ondisconnect();
|
|
|
|
}
|
|
|
|
} else {
|
2020-02-19 09:35:10 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
reconnect(maxRetries, numRetries + 1);
|
2017-09-22 15:57:59 +02:00
|
|
|
}, RETRY_TIME_MS);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
this.close = () => {
|
2017-09-22 15:57:59 +02:00
|
|
|
closing = true;
|
|
|
|
ws.close();
|
|
|
|
};
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
this.reconnectWs = () => {
|
2017-09-22 15:57:59 +02:00
|
|
|
Logger.debug("reconnectWs");
|
2020-02-19 09:35:10 +01:00
|
|
|
reconnect(MAX_RETRIES, 1);
|
2017-09-22 15:57:59 +02:00
|
|
|
};
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
this.send = message => {
|
2017-09-22 15:57:59 +02:00
|
|
|
ws.send(message);
|
|
|
|
};
|
|
|
|
|
2020-02-19 09:35:10 +01:00
|
|
|
this.addEventListener = (type, callback) => {
|
|
|
|
registerMessageHandler = () => {
|
2017-09-22 15:57:59 +02:00
|
|
|
ws.addEventListener(type, callback);
|
|
|
|
};
|
|
|
|
registerMessageHandler();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-01-14 10:18:04 +01:00
|
|
|
module.exports = WebSocketWithReconnection;
|