--- a/svghmi/gen_index_xhtml.xslt Fri Oct 28 09:44:33 2022 +0200
+++ b/svghmi/gen_index_xhtml.xslt Fri Oct 28 10:42:35 2022 +0200
@@ -11289,20 +11289,6 @@
- <xsl:text> window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws')
- <xsl:text> + '?mode=' + (has_watchdog ? "watchdog" : "multiclient");
- <xsl:text>var ws = new WebSocket(ws_url);
- <xsl:text>ws.binaryType = 'arraybuffer';
<xsl:text>const dvgetters = {
<xsl:text> INT: (dv,offset) => [dv.getInt16(offset, true), 2],
@@ -11439,7 +11425,7 @@
<xsl:text>// are stored until browser can compute next frame, DOM is left untouched
- <xsl:text>ws.onmessage = function (evt) {
+ <xsl:text>function ws_onmessage(evt) { @@ -11523,9 +11509,13 @@
+ <xsl:text>var ws = null; <xsl:text>function send_blob(data) {
- <xsl:text> if(data.length > 0) {
+ <xsl:text> if(ws && data.length > 0) { <xsl:text> ws.send(new Blob([hmi_hash_u8].concat(data)));
@@ -11539,9 +11529,9 @@
<xsl:text> INT: (number) => new Int16Array([number]),
- <xsl:text> BOOL: (truth) => new Int16Array([truth]),
- <xsl:text> NODE: (truth) => new Int16Array([truth]),
+ <xsl:text> BOOL: (truth) => new Int8Array([truth]), + <xsl:text> NODE: (truth) => new Int8Array([truth]), <xsl:text> REAL: (number) => new Float32Array([number]),
@@ -11641,6 +11631,16 @@
+ <xsl:text>function reset_subscription_periods() { + <xsl:text> for(let index in subscriptions) + <xsl:text> subscriptions[index][1] = 0; <xsl:text>if(has_watchdog){
<xsl:text> // artificially subscribe the watchdog widget to "/heartbeat" hmi variable
@@ -11839,6 +11839,14 @@
<xsl:text> let delta = [];
+ <xsl:text> // dont' change subscriptions if not connected <xsl:text> for(let index in subscriptions){
<xsl:text> let widgets = subscribers(index);
@@ -12079,17 +12087,19 @@
- <xsl:text>function prepare_svg() {
- <xsl:text> // prevents context menu from appearing on right click and long touch
- <xsl:text> document.body.addEventListener('contextmenu', e => {
- <xsl:text> toggleFullscreen();
- <xsl:text> e.preventDefault();
+ <xsl:text>// prevents context menu from appearing on right click and long touch + <xsl:text>document.body.addEventListener('contextmenu', e => { + <xsl:text> toggleFullscreen(); + <xsl:text> e.preventDefault(); + <xsl:text>function detach_detachables() { @@ -12387,44 +12397,128 @@
+ <xsl:text>// prepare SVG + <xsl:text>apply_reference_frames(); + <xsl:text>init_widgets(); + <xsl:text>detach_detachables(); + <xsl:text>// show main page + <xsl:text>switch_page(default_page); + <xsl:text>var reconnect_delay = 0; + <xsl:text>var periodic_reconnect_timer; <xsl:text>// Once connection established
- <xsl:text>ws.onopen = function (evt) {
- <xsl:text> apply_reference_frames();
- <xsl:text> init_widgets();
+ <xsl:text>function ws_onopen(evt) { + <xsl:text> // Work around memory leak with websocket on QtWebEngine + <xsl:text> // reconnect every hour to force deallocate websocket garbage + <xsl:text> if(window.navigator.userAgent.includes("QtWebEngine")){ + <xsl:text> if(periodic_reconnect_timer){ + <xsl:text> window.clearTimeout(periodic_reconnect_timer); + <xsl:text> periodic_reconnect_timer = window.setTimeout(() => { + <xsl:text> periodic_reconnect_timer = null; + <xsl:text> }, 3600000); + <xsl:text> // forget subscriptions remotely - <xsl:text> // show main page
- <xsl:text> prepare_svg();
- <xsl:text> switch_page(default_page);
+ <xsl:text> // forget earlier subscriptions locally + <xsl:text> reset_subscription_periods(); + <xsl:text> // update PLC about subscriptions and current page + <xsl:text> switch_page(); + <xsl:text> // at first try reconnect immediately + <xsl:text> reconnect_delay = 1; - <xsl:text>ws.onclose = function (evt) {
+ <xsl:text>function ws_onclose(evt) { + <xsl:text> console.log("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+" Reload in "+reconnect_delay+"ms."); <xsl:text> // TODO : add visible notification while waiting for reload
- <xsl:text> console.log("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+" Reload in 10s.");
- <xsl:text> // TODO : re-enable auto reload when not in debug
- <xsl:text> //window.setTimeout(() => location.reload(true), 10000);
- <xsl:text> alert("Connection closed. code:"+evt.code+" reason:"+evt.reason+" wasClean:"+evt.wasClean+".");
+ <xsl:text> window.setTimeout(create_ws, reconnect_delay); + <xsl:text> reconnect_delay += 500; + <xsl:text> window.location.href.replace(/^http(s?:\/\/[^\/]*)\/.*$/, 'ws$1/ws') + <xsl:text> + '?mode=' + (has_watchdog ? "watchdog" : "multiclient"); + <xsl:text>function create_ws(){ + <xsl:text> ws = new WebSocket(ws_url); + <xsl:text> ws.binaryType = 'arraybuffer'; + <xsl:text> ws.onmessage = ws_onmessage; + <xsl:text> ws.onclose = ws_onclose; + <xsl:text> ws.onopen = ws_onopen; <xsl:text>const xmlns = "http://www.w3.org/2000/svg";
<xsl:text>var edit_callback;