var sshTerm = null; var sshFit = null; var sshWS = null; var sshResizeTimer = null; function initPage8() { var el = document.getElementById("ssh-terminal"); if (!el || sshTerm) { return; } // xterm.js 不支持 IE 等老浏览器, 优雅降级提示 if (typeof Terminal === "undefined") { el.innerHTML = '
' + "当前浏览器不支持 SSH 终端组件。
" + "请使用 Chrome、Edge、Firefox 等现代浏览器访问该功能。
"; return; } sshTerm = new Terminal({ cursorBlink: true, scrollback: 2000, fontSize: 14, convertEol: true, theme: { background: "#111111", }, }); sshFit = new FitAddon.FitAddon(); sshTerm.loadAddon(sshFit); sshTerm.open(el); sshTerm.onData(function (data) { if ((sshWS && sshWS.readyState) === WebSocket.OPEN) { sshWS.send( JSON.stringify({ type: "input", data: data, }) ); } }); connectSSH(); window.addEventListener("resize", resizeSSH); resizeSSH(); } function connectSSH() { sshWS = new WebSocket( (location.protocol === "https:" ? "wss://" : "ws://") + location.host + "/api/ssh/ws" ); sshWS.binaryType = "arraybuffer"; sshWS.onopen = function () { resizeSSH(); sshTerm && sshTerm.focus(); }; sshWS.onmessage = function (e) { sshTerm && sshTerm.write(new Uint8Array(e.data)); }; sshWS.onclose = function () { sshWS = null; sshTerm && sshTerm.write("\r\n\x1b[33m[Connection closed]\x1b[0m\r\n"); }; } function resizeSSH() { if (!sshFit || !sshTerm) { return; } clearTimeout(sshResizeTimer); sshResizeTimer = null; sshResizeTimer = setTimeout(function () { if (!sshTerm || !sshFit) { return; } sshFit.fit(); if ((sshWS && sshWS.readyState) === WebSocket.OPEN) { sshWS.send( JSON.stringify({ type: "resize", cols: sshTerm.cols, rows: sshTerm.rows, }) ); } }, 100); } function exitPage8() { window.removeEventListener("resize", resizeSSH); clearTimeout(sshResizeTimer); if (sshWS) { sshWS.onclose = null; sshWS.close(); sshWS = null; } sshTerm && sshTerm.dispose(); sshTerm = null; sshFit = null; }