mirror of https://github.com/OpenVidu/openvidu.git
openvidu-browser: reconnection fix for unexpected ws close (HttpSession expiring)
parent
05dc6e21aa
commit
cb8594373e
|
@ -59,6 +59,11 @@ export class Connection {
|
|||
*/
|
||||
disposed = false;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
rpcSessionId: string;
|
||||
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
|
|
|
@ -91,7 +91,7 @@ export class OpenVidu {
|
|||
const getNewVideoDimensions = (): Promise<{ newWidth: number, newHeight: number }> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (platform['isIonicIos']) {
|
||||
// iOS Ionic. Limitation: must get new dimensions from an existing video element already inserted into DOM
|
||||
// iOS Ionic. Limitation: must get new dimensions from an existing video element already inserted into DOM
|
||||
resolve({
|
||||
newWidth: publisher.stream.streamManager.videos[0].video.videoWidth,
|
||||
newHeight: publisher.stream.streamManager.videos[0].video.videoHeight
|
||||
|
@ -636,7 +636,7 @@ export class OpenVidu {
|
|||
* @hidden
|
||||
*/
|
||||
closeWs(): void {
|
||||
this.jsonRpcClient.close();
|
||||
this.jsonRpcClient.close(4102, "Connection closed by client");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -678,7 +678,7 @@ export class OpenVidu {
|
|||
private disconnectCallback(): void {
|
||||
console.warn('Websocket connection lost');
|
||||
if (this.isRoomAvailable()) {
|
||||
this.session.onLostConnection();
|
||||
this.session.onLostConnection('networkDisconnect');
|
||||
} else {
|
||||
alert('Connection error. Please reload page.');
|
||||
}
|
||||
|
@ -686,9 +686,7 @@ export class OpenVidu {
|
|||
|
||||
private reconnectingCallback(): void {
|
||||
console.warn('Websocket connection lost (reconnecting)');
|
||||
if (this.isRoomAvailable()) {
|
||||
this.session.onLostConnection();
|
||||
} else {
|
||||
if (!this.isRoomAvailable()) {
|
||||
alert('Connection error. Please reload page.');
|
||||
}
|
||||
}
|
||||
|
@ -696,7 +694,16 @@ export class OpenVidu {
|
|||
private reconnectedCallback(): void {
|
||||
console.warn('Websocket reconnected');
|
||||
if (this.isRoomAvailable()) {
|
||||
this.session.onRecoveredConnection();
|
||||
this.sendRequest('connect', { sessionId: this.session.connection.rpcSessionId }, (error, response) => {
|
||||
if (!!error) {
|
||||
console.error(error);
|
||||
this.session.onLostConnection("networkDisconnect");
|
||||
this.jsonRpcClient.close(4101, "Reconnection fault");
|
||||
} else {
|
||||
this.jsonRpcClient.resetPing();
|
||||
this.session.onRecoveredConnection();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('Connection error. Please reload page.');
|
||||
}
|
||||
|
|
|
@ -899,22 +899,10 @@ export class Session implements EventDispatcher {
|
|||
/**
|
||||
* @hidden
|
||||
*/
|
||||
onLostConnection(): void {
|
||||
|
||||
/*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);
|
||||
onLostConnection(reason: string): void {
|
||||
console.warn('Lost connection in session ' + this.sessionId + ' waiting for reconnect');
|
||||
if (!!this.sessionId && !this.connection.disposed) {
|
||||
this.leave(true, 'networkDisconnect');
|
||||
this.leave(true, reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -923,7 +911,7 @@ export class Session implements EventDispatcher {
|
|||
*/
|
||||
onRecoveredConnection(): void {
|
||||
console.warn('Recovered connection in Session ' + this.sessionId);
|
||||
this.ee.emitEvent('connectionRecovered', []);
|
||||
// this.ee.emitEvent('connectionRecovered', []);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1048,6 +1036,7 @@ export class Session implements EventDispatcher {
|
|||
this.connection.connectionId = response.id;
|
||||
this.connection.creationTime = response.createdAt;
|
||||
this.connection.data = response.metadata;
|
||||
this.connection.rpcSessionId = response.sessionId;
|
||||
|
||||
// Initialize remote Connections with value returned by openvidu-server
|
||||
const events = {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
var RpcBuilder = require('../');
|
||||
var WebSocketWithReconnection = require('./transports/webSocketWithReconnection');
|
||||
|
||||
Date.now = Date.now || function() {
|
||||
Date.now = Date.now || function () {
|
||||
return +new Date;
|
||||
};
|
||||
|
||||
|
@ -39,7 +39,7 @@ var Logger = console;
|
|||
* 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,
|
||||
* 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,
|
||||
* onerror : callback method to invoke when there is an error
|
||||
|
@ -71,24 +71,26 @@ function JsonRpcClient(configuration) {
|
|||
var onconnected = wsConfig.onconnected;
|
||||
var onerror = wsConfig.onerror;
|
||||
|
||||
configuration.rpc.pull = function(params, request) {
|
||||
configuration.rpc.pull = function (params, request) {
|
||||
request.reply(null, "push");
|
||||
}
|
||||
|
||||
wsConfig.onreconnecting = function() {
|
||||
wsConfig.onreconnecting = function () {
|
||||
Logger.debug("--------- ONRECONNECTING -----------");
|
||||
if (status === RECONNECTING) {
|
||||
Logger.error("Websocket already in RECONNECTING state when receiving a new ONRECONNECTING message. Ignoring it");
|
||||
return;
|
||||
}
|
||||
|
||||
stopPing();
|
||||
|
||||
status = RECONNECTING;
|
||||
if (onreconnecting) {
|
||||
onreconnecting();
|
||||
}
|
||||
}
|
||||
|
||||
wsConfig.onreconnected = function() {
|
||||
wsConfig.onreconnected = function () {
|
||||
Logger.debug("--------- ONRECONNECTED -----------");
|
||||
if (status === CONNECTED) {
|
||||
Logger.error("Websocket already in CONNECTED state when receiving a new ONRECONNECTED message. Ignoring it");
|
||||
|
@ -96,16 +98,14 @@ function JsonRpcClient(configuration) {
|
|||
}
|
||||
status = CONNECTED;
|
||||
|
||||
enabledPings = true;
|
||||
updateNotReconnectIfLessThan();
|
||||
usePing();
|
||||
|
||||
if (onreconnected) {
|
||||
onreconnected();
|
||||
}
|
||||
}
|
||||
|
||||
wsConfig.onconnected = function() {
|
||||
wsConfig.onconnected = function () {
|
||||
Logger.debug("--------- ONCONNECTED -----------");
|
||||
if (status === CONNECTED) {
|
||||
Logger.error("Websocket already in CONNECTED state when receiving a new ONCONNECTED message. Ignoring it");
|
||||
|
@ -121,11 +121,13 @@ function JsonRpcClient(configuration) {
|
|||
}
|
||||
}
|
||||
|
||||
wsConfig.onerror = function(error) {
|
||||
wsConfig.onerror = function (error) {
|
||||
Logger.debug("--------- ONERROR -----------");
|
||||
|
||||
status = DISCONNECTED;
|
||||
|
||||
stopPing();
|
||||
|
||||
if (onerror) {
|
||||
onerror(error);
|
||||
}
|
||||
|
@ -141,7 +143,7 @@ function JsonRpcClient(configuration) {
|
|||
};
|
||||
|
||||
var rpc = new RpcBuilder(RpcBuilder.packers.JsonRPC, rpcBuilderOptions, ws,
|
||||
function(request) {
|
||||
function (request) {
|
||||
|
||||
Logger.debug('Received request: ' + JSON.stringify(request));
|
||||
|
||||
|
@ -159,14 +161,14 @@ function JsonRpcClient(configuration) {
|
|||
}
|
||||
});
|
||||
|
||||
this.send = function(method, params, callback) {
|
||||
this.send = function (method, params, callback) {
|
||||
if (method !== 'ping') {
|
||||
Logger.debug('Request: method:' + method + " params:" + JSON.stringify(params));
|
||||
}
|
||||
|
||||
var requestTime = Date.now();
|
||||
|
||||
rpc.encode(method, params, function(error, result) {
|
||||
rpc.encode(method, params, function (error, result) {
|
||||
if (error) {
|
||||
try {
|
||||
Logger.error("ERROR:" + error.message + " in Request: method:" +
|
||||
|
@ -203,8 +205,8 @@ function JsonRpcClient(configuration) {
|
|||
}
|
||||
pingNextNum++;
|
||||
|
||||
self.send('ping', params, (function(pingNum) {
|
||||
return function(error, result) {
|
||||
self.send('ping', params, (function (pingNum) {
|
||||
return function (error, result) {
|
||||
if (error) {
|
||||
Logger.debug("Error in ping request #" + pingNum + " (" +
|
||||
error.message + ")");
|
||||
|
@ -224,9 +226,9 @@ function JsonRpcClient(configuration) {
|
|||
}
|
||||
|
||||
/*
|
||||
* If configuration.hearbeat has any value, the ping-pong will work with the interval
|
||||
* of configuration.hearbeat
|
||||
*/
|
||||
* If configuration.hearbeat has any value, the ping-pong will work with the interval
|
||||
* of configuration.hearbeat
|
||||
*/
|
||||
function usePing() {
|
||||
if (!pingPongStarted) {
|
||||
Logger.debug("Starting ping (if configured)")
|
||||
|
@ -239,8 +241,16 @@ function JsonRpcClient(configuration) {
|
|||
}
|
||||
}
|
||||
|
||||
this.close = function() {
|
||||
Logger.debug("Closing jsonRpcClient explicitly by client");
|
||||
function stopPing() {
|
||||
clearInterval(pingInterval);
|
||||
pingPongStarted = false;
|
||||
enabledPings = false;
|
||||
pingNextNum = -1;
|
||||
rpc.cancel();
|
||||
}
|
||||
|
||||
this.close = function (code, reason) {
|
||||
Logger.debug("Closing with code: " + code + " because: " + reason);
|
||||
|
||||
if (pingInterval != undefined) {
|
||||
Logger.debug("Clearing ping interval");
|
||||
|
@ -251,26 +261,32 @@ function JsonRpcClient(configuration) {
|
|||
|
||||
if (configuration.sendCloseMessage) {
|
||||
Logger.debug("Sending close message")
|
||||
this.send('closeSession', null, function(error, result) {
|
||||
this.send('closeSession', null, function (error, result) {
|
||||
if (error) {
|
||||
Logger.error("Error sending close message: " + JSON.stringify(error));
|
||||
}
|
||||
ws.close();
|
||||
ws.close(code, reason);
|
||||
});
|
||||
} else {
|
||||
ws.close();
|
||||
ws.close(code, reason);
|
||||
}
|
||||
}
|
||||
|
||||
// This method is only for testing
|
||||
this.forceClose = function(millis) {
|
||||
this.forceClose = function (millis) {
|
||||
ws.forceClose(millis);
|
||||
}
|
||||
|
||||
this.reconnect = function() {
|
||||
this.reconnect = function () {
|
||||
ws.reconnectWs();
|
||||
}
|
||||
|
||||
this.resetPing = function () {
|
||||
enabledPings = true;
|
||||
pingNextNum = 0;
|
||||
usePing();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = JsonRpcClient;
|
||||
module.exports = JsonRpcClient;
|
|
@ -48,7 +48,7 @@ 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,
|
||||
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,
|
||||
};
|
||||
|
@ -71,14 +71,14 @@ function WebSocketWithReconnection(config) {
|
|||
ws = new WebSocket(wsUri);
|
||||
}
|
||||
|
||||
ws.onopen = function() {
|
||||
ws.onopen = function () {
|
||||
logConnected(ws, wsUri);
|
||||
if (config.onconnected) {
|
||||
config.onconnected();
|
||||
}
|
||||
};
|
||||
|
||||
ws.onerror = function(error) {
|
||||
ws.onerror = function (error) {
|
||||
Logger.error("Could not connect to " + wsUri + " (invoking onerror if defined)", error);
|
||||
if (config.onerror) {
|
||||
config.onerror(error);
|
||||
|
@ -93,7 +93,7 @@ function WebSocketWithReconnection(config) {
|
|||
}
|
||||
}
|
||||
|
||||
var reconnectionOnClose = function() {
|
||||
var reconnectionOnClose = function () {
|
||||
if (ws.readyState === CLOSED) {
|
||||
if (closing) {
|
||||
Logger.debug("Connection closed by user");
|
||||
|
@ -129,11 +129,11 @@ function WebSocketWithReconnection(config) {
|
|||
|
||||
} else {
|
||||
if (config.newWsUriOnReconnection) {
|
||||
config.newWsUriOnReconnection(function(error, newWsUri) {
|
||||
config.newWsUriOnReconnection(function (error, newWsUri) {
|
||||
|
||||
if (error) {
|
||||
Logger.debug(error);
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
reconnectToSameUri(maxRetries, numRetries + 1);
|
||||
}, RETRY_TIME_MS);
|
||||
} else {
|
||||
|
@ -161,7 +161,7 @@ function WebSocketWithReconnection(config) {
|
|||
newWs = new WebSocket(wsUri);
|
||||
}
|
||||
|
||||
newWs.onopen = function() {
|
||||
newWs.onopen = function () {
|
||||
Logger.debug("Reconnected after " + numRetries + " attempts...");
|
||||
logConnected(newWs, wsUri);
|
||||
reconnecting = false;
|
||||
|
@ -173,7 +173,7 @@ function WebSocketWithReconnection(config) {
|
|||
newWs.onclose = reconnectionOnClose;
|
||||
};
|
||||
|
||||
var onErrorOrClose = function(error) {
|
||||
var onErrorOrClose = function (error) {
|
||||
Logger.warn("Reconnection error: ", error);
|
||||
|
||||
if (numRetries === maxRetries) {
|
||||
|
@ -181,7 +181,7 @@ function WebSocketWithReconnection(config) {
|
|||
config.ondisconnect();
|
||||
}
|
||||
} else {
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
reconnectToSameUri(maxRetries, numRetries + 1);
|
||||
}, RETRY_TIME_MS);
|
||||
}
|
||||
|
@ -192,14 +192,14 @@ function WebSocketWithReconnection(config) {
|
|||
ws = newWs;
|
||||
}
|
||||
|
||||
this.close = function() {
|
||||
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");
|
||||
|
||||
if (millis) {
|
||||
|
@ -209,7 +209,7 @@ function WebSocketWithReconnection(config) {
|
|||
|
||||
forcingDisconnection = true;
|
||||
|
||||
setTimeout(function() {
|
||||
setTimeout(function () {
|
||||
Logger.debug("Testing: Recover good wsUri " + goodWsUri);
|
||||
wsUri = goodWsUri;
|
||||
|
||||
|
@ -221,17 +221,17 @@ function WebSocketWithReconnection(config) {
|
|||
ws.close();
|
||||
};
|
||||
|
||||
this.reconnectWs = function() {
|
||||
this.reconnectWs = function () {
|
||||
Logger.debug("reconnectWs");
|
||||
reconnectToSameUri(MAX_RETRIES, 1);
|
||||
};
|
||||
|
||||
this.send = function(message) {
|
||||
this.send = function (message) {
|
||||
ws.send(message);
|
||||
};
|
||||
|
||||
this.addEventListener = function(type, callback) {
|
||||
registerMessageHandler = function() {
|
||||
this.addEventListener = function (type, callback) {
|
||||
registerMessageHandler = function () {
|
||||
ws.addEventListener(type, callback);
|
||||
};
|
||||
|
||||
|
@ -239,4 +239,4 @@ function WebSocketWithReconnection(config) {
|
|||
};
|
||||
}
|
||||
|
||||
module.exports = WebSocketWithReconnection;
|
||||
module.exports = WebSocketWithReconnection;
|
|
@ -519,7 +519,7 @@ function RpcBuilder(packer, options, transport, onRequest)
|
|||
// Prevent to receive new messages
|
||||
var transport = this.getTransport();
|
||||
if(transport && transport.close)
|
||||
transport.close();
|
||||
transport.close(4003, "Cancel request");
|
||||
|
||||
// Request & processed responses
|
||||
this.cancel();
|
||||
|
|
Loading…
Reference in New Issue