<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="xterm.css" /> <script src="xterm.js"></script> <script src="xterm-addon-fit.js"></script> <script src="jquery.js"></script> </head> <style> body { font-family: sans; } </style> <body> <div id="terminal" style="height: 90vh"></div> <div id="status">Connecting...</div> <script> var line_items = []; var idx = -1; var term = new Terminal({ cursorBlink: true, convertEol: true }); var fitAddon = new FitAddon.FitAddon(); term.loadAddon(fitAddon); var socket; var firstConnection = true; function createSocket() { if (socket && !socket.replacementCreated) { socket.close(); } socket = new WebSocket("ws://" + window.location.host + "/ws/debug"); socket.binaryType = 'arraybuffer'; socket.replacementCreated = false; socket.ontimeout = function () { if (socket.readyState == WebSocket.OPEN) { socket.send(''); } }; socket.onmessage = function (event) { term.write(new Uint8Array(event.data)); }; socket.onerror = function (event) { socket.close(); } socket.onclose = function (event) { socket.onerror = undefined; socket.onclose = undefined; if (event.wasClean) { $("#status").text("Connection closed"); } else { $("#status").text("Reconnecting..."); } clearInterval(socket.intervalId); if (!socket.replacementCreated) { socket.replacementCreated = true; createSocket(); } else { console.log("a replacement socket was already being created -- skipping"); } }; socket.onopen = function (event) { $("#status").text("Connected"); if (firstConnection) { term.write("\x1B[1;3;31m[Websocket] Connection established\x1B[0m\r\n"); } else { term.write("[Websocket] Connection reestablished\n"); } firstConnection = false; }; socket.intervalId = setInterval(socket.ontimeout, 2000, socket); } createSocket(); term.open(document.getElementById('terminal')); fitAddon.activate(term) fitAddon.fit() term.focus() window.addEventListener('resize', () => { fitAddon.fit() }); </script> </body> </html>