diff options
Diffstat (limited to 'web/share/js/kvm/session.js')
-rw-r--r-- | web/share/js/kvm/session.js | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/web/share/js/kvm/session.js b/web/share/js/kvm/session.js new file mode 100644 index 00000000..5ba43511 --- /dev/null +++ b/web/share/js/kvm/session.js @@ -0,0 +1,133 @@ +function Session() { + // var self = this; + + /********************************************************************************/ + + var __ws = null; + + var __ping_timer = null; + var __missed_heartbeats = 0; + + var __hid = new Hid(); + var __atx = new Atx(); + var __msd = new Msd(); + var __streamer = new Streamer(); + + var __init__ = function() { + __startSession(); + }; + + /********************************************************************************/ + + var __setKvmdInfo = function(state) { + if (state.meta) { + var text = JSON.stringify(state.meta, undefined, 4).replace(/ /g, " ").replace(/\n/g, "<br>"); + $("about-meta").innerHTML = ` + <span class="code-comment">// The Pi-KVM metadata.<br> + // You can get this json using handle <a target="_blank" href="/kvmd/info">/kvmd/info</a>.<br> + // In the standard configuration this data<br> + // is specified in the file /etc/kvmd/meta.yaml.</span><br> + <br> + ${text} + `; + if (state.meta.server && state.meta.server.host) { + $("kvmd-meta-server-host").innerHTML = "Server: " + state.meta.server.host; + document.title = "Pi-KVM Session: " + state.meta.server.host; + } else { + $("kvmd-meta-server-host").innerHTML = ""; + document.title = "Pi-KVM Session"; + } + } + + $("about-version-kvmd").innerHTML = state.version.kvmd; + $("about-version-streamer").innerHTML = `${state.version.streamer} (${state.streamer})`; + }; + + var __startSession = function() { + $("link-led").className = "led-yellow"; + $("link-led").title = "Connecting..."; + var proto = (location.protocol === "https:" ? "wss" : "ws"); + __ws = new WebSocket(`${proto}://${location.host}/kvmd/ws`); + __ws.onopen = __wsOpenHandler; + __ws.onmessage = __wsMessageHandler; + __ws.onerror = __wsErrorHandler; + __ws.onclose = __wsCloseHandler; + }; + + var __wsOpenHandler = function(event) { + tools.debug("Session: socket opened:", event); + $("link-led").className = "led-green"; + $("link-led").title = "Connected"; + __hid.setSocket(__ws); + __missed_heartbeats = 0; + __ping_timer = setInterval(__pingServer, 1000); + }; + + var __wsMessageHandler = function(event) { + // tools.debug("Session: received socket data:", event.data); + event = JSON.parse(event.data); + if (event.msg_type === "pong") { + __missed_heartbeats = 0; + } else if (event.msg_type === "event") { + if (event.msg.event === "info_state") { + __setKvmdInfo(event.msg.event_attrs); + } else if (event.msg.event === "atx_state") { + __atx.setState(event.msg.event_attrs); + } else if (event.msg.event === "msd_state") { + __msd.setState(event.msg.event_attrs); + } else if (event.msg.event === "streamer_state") { + __streamer.setState(event.msg.event_attrs); + } + } + }; + + var __wsErrorHandler = function(event) { + tools.error("Session: socket error:", event); + if (__ws) { + __ws.onclose = null; + __ws.close(); + __wsCloseHandler(null); + } + }; + + var __wsCloseHandler = function(event) { + tools.debug("Session: socket closed:", event); + + $("link-led").className = "led-gray"; + + if (__ping_timer) { + clearInterval(__ping_timer); + __ping_timer = null; + } + + __hid.setSocket(null); + __atx.setState(null); + __msd.setState(null); + __streamer.setState(null); + __ws = null; + + setTimeout(function() { + $("link-led").className = "led-yellow"; + setTimeout(__startSession, 500); + }, 500); + }; + + var __pingServer = function() { + try { + __missed_heartbeats += 1; + if (__missed_heartbeats >= 5) { + throw new Error("Too many missed heartbeats"); + } + __ws.send(JSON.stringify({"event_type": "ping"})); + } catch (err) { + tools.error("Session: ping error:", err.message); + if (__ws) { + __ws.onclose = null; + __ws.close(); + __wsCloseHandler(null); + } + } + }; + + __init__(); +} |