mirror of
https://gitlab.com/crafty-controller/crafty-4.git
synced 2024-08-30 18:23:09 +00:00
Merge branch 'bugfix/reconnecting-websocket' into 'dev'
Make the WebSocket automatically reconnect. See merge request crafty-controller/crafty-4!345
This commit is contained in:
commit
fff186e547
@ -163,8 +163,29 @@
|
|||||||
<script type="text/javascript" src="/static/assets/js/motd.js"></script>
|
<script type="text/javascript" src="/static/assets/js/motd.js"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/**
|
||||||
|
* Returns a random number between min (inclusive) and max (exclusive)
|
||||||
|
*/
|
||||||
|
function getRandomArbitrary(min, max) {
|
||||||
|
return Math.random() * (max - min) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random integer between min (inclusive) and max (inclusive).
|
||||||
|
* The value is no lower than min (or the next integer greater than min
|
||||||
|
* if min isn't an integer) and no greater than max (or the next integer
|
||||||
|
* lower than max if max isn't an integer).
|
||||||
|
* Using Math.round() will give you a non-uniform distribution!
|
||||||
|
*/
|
||||||
|
function getRandomInt(min, max) {
|
||||||
|
min = Math.ceil(min);
|
||||||
|
max = Math.floor(max);
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$.extend($.fn.dataTable.defaults, {
|
$.extend($.fn.dataTable.defaults, {
|
||||||
language: {% raw translate('datatables', 'i18n', data['lang']) %}
|
// {{ '\nlanguage:' }} {% raw translate('datatables', 'i18n', data['lang']) %}
|
||||||
})
|
})
|
||||||
|
|
||||||
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
|
//used to get cookies from browser - this is part of tornados xsrf protection - it's for extra security
|
||||||
@ -192,17 +213,41 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let usingWebSockets = false;
|
||||||
|
let webSocket = null;
|
||||||
// {% if request.protocol == 'https' %}
|
// {% if request.protocol == 'https' %}
|
||||||
let usingWebSockets = true;
|
usingWebSockets = true;
|
||||||
|
|
||||||
let listenEvents = [];
|
let listenEvents = [];
|
||||||
|
let wsOpen = false;
|
||||||
|
/**
|
||||||
|
* @type {number | null} reconnectorId An interval ID for the reconnector.
|
||||||
|
*/
|
||||||
|
let reconnectorId = null;
|
||||||
|
let failedConnectionCounter = 0; // https://stackoverflow.com/a/37038217/15388424
|
||||||
|
|
||||||
|
const wsPageQueryParams = 'page_query_params=' + encodeURIComponent(location.search)
|
||||||
|
const wsPage = 'page=' + encodeURIComponent(location.pathname)
|
||||||
|
|
||||||
|
const sendWssError = () => wsOpen || warn(
|
||||||
|
'WebSockets are required for Crafty to work. This websocket connection has been closed. Are you using a reverse proxy?',
|
||||||
|
'https://wiki.craftycontrol.com/en/4/docs/Reverse%20Proxy%20Examples',
|
||||||
|
'wssError'
|
||||||
|
)
|
||||||
|
|
||||||
|
function startWebSocket() {
|
||||||
|
console.log('%c[Crafty Controller] %cConnecting the WebSocket', 'font-weight: 900; color: #800080;', 'font-weight: 900; color: #eee;');
|
||||||
try {
|
try {
|
||||||
pageQueryParams = 'page_query_params=' + encodeURIComponent(location.search)
|
var wsInternal = new WebSocket('wss://' + location.host + '/ws?' + wsPage + '&' + wsPageQueryParams);
|
||||||
page = 'page=' + encodeURIComponent(location.pathname)
|
|
||||||
var wsInternal = new WebSocket('wss://' + location.host + '/ws?' + page + '&' + pageQueryParams);
|
|
||||||
wsInternal.onopen = function () {
|
wsInternal.onopen = function () {
|
||||||
console.log('opened WebSocket connection:', wsInternal)
|
console.log('opened WebSocket connection:', wsInternal)
|
||||||
|
wsOpen = true;
|
||||||
|
failedConnectionCounter = 0;
|
||||||
|
if (typeof reconnectorId === 'number') {
|
||||||
|
document.querySelectorAll('.wssError').forEach(el => el.remove())
|
||||||
|
clearInterval(reconnectorId);
|
||||||
|
reconnectorId = null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
wsInternal.onmessage = function (rawMessage) {
|
wsInternal.onmessage = function (rawMessage) {
|
||||||
var message = JSON.parse(rawMessage.data);
|
var message = JSON.parse(rawMessage.data);
|
||||||
@ -215,12 +260,20 @@
|
|||||||
};
|
};
|
||||||
wsInternal.onerror = function (errorEvent) {
|
wsInternal.onerror = function (errorEvent) {
|
||||||
console.error('WebSocket Error', errorEvent);
|
console.error('WebSocket Error', errorEvent);
|
||||||
warn('WebSockets are required for Crafty to work. This websocket connection has been closed. Are you using a reverse proxy?', 'https://wiki.craftycontrol.com/en/4/docs/Reverse%20Proxy%20Examples')
|
|
||||||
|
|
||||||
};
|
};
|
||||||
wsInternal.onclose = function (closeEvent) {
|
wsInternal.onclose = function (closeEvent) {
|
||||||
|
wsOpen = false;
|
||||||
console.log('Closed WebSocket', closeEvent);
|
console.log('Closed WebSocket', closeEvent);
|
||||||
|
|
||||||
|
if (typeof reconnectorId !== 'number') {
|
||||||
setTimeout(sendWssError, 7000);
|
setTimeout(sendWssError, 7000);
|
||||||
|
}
|
||||||
|
console.info("Reconnecting with a timeout of", (getRandomArbitrary(0, 2 ** failedConnectionCounter - 1) + 5) * 1000, "milliseconds");
|
||||||
|
// Discard old websocket and create a new one in 5 seconds
|
||||||
|
wsInternal = null
|
||||||
|
reconnectorId = setTimeout(startWebSocket, (getRandomArbitrary(0, 2 ** failedConnectionCounter - 1) + 5) * 1000)
|
||||||
|
|
||||||
|
failedConnectionCounter++;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -242,10 +295,11 @@
|
|||||||
console.error('Error while making websocket helpers', error);
|
console.error('Error while making websocket helpers', error);
|
||||||
usingWebSockets = false;
|
usingWebSockets = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startWebSocket();
|
||||||
// {% else %}
|
// {% else %}
|
||||||
let usingWebSockets = false;
|
|
||||||
warn('WebSockets are not supported in Crafty if not using the https protocol')
|
warn('WebSockets are not supported in Crafty if not using the https protocol')
|
||||||
var webSocket;
|
|
||||||
// {% end%}
|
// {% end%}
|
||||||
|
|
||||||
if (webSocket) {
|
if (webSocket) {
|
||||||
@ -265,8 +319,6 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (webSocket) {
|
|
||||||
webSocket.on('support_status_update', function (logs) {
|
webSocket.on('support_status_update', function (logs) {
|
||||||
if (logs.percent >= 100) {
|
if (logs.percent >= 100) {
|
||||||
document.getElementById('logs_progress_bar').innerHTML = '100%';
|
document.getElementById('logs_progress_bar').innerHTML = '100%';
|
||||||
@ -276,8 +328,6 @@
|
|||||||
document.getElementById('logs_progress_bar').style.width = logs.percent + '%';
|
document.getElementById('logs_progress_bar').style.width = logs.percent + '%';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if (webSocket) {
|
|
||||||
webSocket.on('send_logs_bootbox', function (server_id) {
|
webSocket.on('send_logs_bootbox', function (server_id) {
|
||||||
var x = document.querySelector('.bootbox');
|
var x = document.querySelector('.bootbox');
|
||||||
if (x) {
|
if (x) {
|
||||||
@ -302,9 +352,6 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (webSocket) {
|
|
||||||
webSocket.on('send_eula_bootbox', function (server_id) {
|
webSocket.on('send_eula_bootbox', function (server_id) {
|
||||||
var x = document.querySelector('.bootbox');
|
var x = document.querySelector('.bootbox');
|
||||||
if (x) {
|
if (x) {
|
||||||
@ -339,10 +386,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendWssError(){
|
|
||||||
warn('WebSockets are required for Crafty to work. This websocket connection has been closed. Are you using a reverse proxy?', 'https://wiki.craftycontrol.com/en/4/docs/Reverse%20Proxy%20Examples')
|
|
||||||
}
|
|
||||||
|
|
||||||
function eulaAgree(server_id, command) {
|
function eulaAgree(server_id, command) {
|
||||||
//< !--this getCookie function is in base.html-- >
|
//< !--this getCookie function is in base.html-- >
|
||||||
var token = getCookie("_xsrf");
|
var token = getCookie("_xsrf");
|
||||||
@ -360,7 +403,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function warn(message, link = null) {
|
function warn(message, link = null, className = null) {
|
||||||
var closeEl = document.createElement('span');
|
var closeEl = document.createElement('span');
|
||||||
var strongEL = document.createElement('strong');
|
var strongEL = document.createElement('strong');
|
||||||
var msgEl = document.createElement('div');
|
var msgEl = document.createElement('div');
|
||||||
@ -397,6 +440,10 @@
|
|||||||
parentEl.appendChild(linkEl);
|
parentEl.appendChild(linkEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (className) {
|
||||||
|
parentEl.classList.add(className);
|
||||||
|
}
|
||||||
|
|
||||||
document.querySelector('.warnings').appendChild(parentEl);
|
document.querySelector('.warnings').appendChild(parentEl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user