<script>
let wsTime = null;
new Vue({
el: "#app",
data() {
return {
// 終端
term: {},
// websocket
ws: {},
// 用戶輸入
command: "",
};
},
created() {
// 初始化終端
this.initTerminal();
},
mounted() {
// 建立websocket連接
this.websocket();
},
beforeDestroy() {
this.ws.close();
this.term.dispose();
},
methods: {
// 初始化終端配置
initTerminal() {
this.term = new Terminal({
rendererType: "canvas", //渲染類型
// rows: 40, //行數,影響最小高度
cols: 100, // 列數,影響最小寬度
convertEol: true, //啓用時,光標將設置爲下一行的開頭
// scrollback: 50, //終端中的滾動條回滾量
disableStdin: false, //是否應禁用輸入。
cursorStyle: "underline", //光標樣式
cursorBlink: true, //光標閃爍
theme: {
foreground: "#F8F8F8",
background: "#2D2E2C",
cursor: "help", //設置光標
lineHeight: 16,
},
fontFamily: '"Cascadia Code", Menlo, monospace',
});
},
// 自定義終端默認展示內容
writeDefaultInfo() {
let defaultInfo = [
"┌\x1b[1m terminals \x1b[0m─────────────────────────────────────────────────────────────────┐ ",
"│ │ ",
"│ \x1b[1;34m 歡迎使用Web Docker SSH \x1b[0m │ ",
"│ │ ",
"└────────────────────────────────────────────────────────────────────────────┘ ",
];
// 測試顏色區間
// let arr = Array.from({length:100},(v,i)=>v = i)
// console.log(arr)
// arr.map((item,i) => {
// defaultInfo.push(`Hello from \x1B[1;3;${i}m ${i} \x1B[0m \u2764\ufe0f ${i}`)
// })
this.term.write(defaultInfo.join("\n\r"));
this.writeOfColor("我是加粗斜體紅色的字呀", "1;3;", "31m");
// this.term.write('\n\r$ ')
},
//
writeOfColor(txt, fontCss = "", bgColor = "") {
// 在Linux腳本中以 \x1B[ 開始,中間前部分是樣式+內容,以 \x1B[0m 結尾
// 示例 \x1B[1;3;31m 內容 \x1B[0m
// fontCss
// 0;-4;字體樣式(0;正常 1;加粗 2;變細 3;斜體 4;下劃線)
// bgColor
// 30m-37m字體顏色(30m:黑色 31m:紅色 32m:綠色 33m:棕色字 34m:藍色 35m:洋紅色/紫色 36m:藍綠色/淺藍色 37m:白色)
// 40m-47m背景顏色(40m:黑色 41m:紅色 42m:綠色 43m:棕色字 44m:藍色 45m:洋紅色/紫色 46m:藍綠色/淺藍色 47m:白色)
this.term.write(`\x1B[${fontCss}${bgColor}${txt}\x1B[0m`);
},
// 監聽輸入
userWrite() {
this.term.onData((e) => {
switch (e) {
case "\u0003": // Ctrl+C
this.term.write("^C ");
this.term.write("\r\n$ ");
break;
case "\r": // Enter
this.ws.send(JSON.stringify({ message: this.command }));//根據後臺返回的數據,需要傳入一個對象,裏邊key值爲message,並對這個對象進行序列化
// this.ws.send("\n");//這邊原來是放開狀態,但由於後臺數據返回原因會報錯,就直接註釋了
this.command = "";
// this.term.write('\r\n$ ')
break;
case "\u007F": // Backspace (DEL)
// Do not delete the prompt
if (this.term._core.buffer.x > 2) {
this.term.write("\b \b");
if (this.command.length > 0) {
this.command = this.command.substr(
0,
this.command.length - 1
);
}
}
break;
default: // Print all other characters for demo
if (
(e >= String.fromCharCode(0x20) &&
e <= String.fromCharCode(0x7e)) ||
e >= "\u00a0"
) {
this.command += e;
this.writeOfColor(e, "2;3;", "33m");
console.log("用戶輸入command", this.command);
}
}
});
},
// 建立websocket連接
websocket() {
// WebSocket start
if ("WebSocket" in window) {
//需要修改ip和id
//例如:const url = `ws://192.168.111.222:2375/v1.41/containers/0eb8aafb4e6e/attach/ws?logs=0&stream=1&stdin=1&stdout=1&stderr=1`
const url = `ws:172.16.188.58:5000/ws/chat/?host=172.16.188.58&username=root&password=admin`;
const ws = new WebSocket(url);
this.ws = ws;
this.$nextTick(() => {
this.userWrite();
});
ws.onopen = (event) => {
console.log("已建立連接:", event);
// 輸入換行符可讓終端顯示當前用戶的工作路徑
// ws.send("\n");//這邊原來是放開狀態,但由於後臺數據返回原因會報錯,就直接註釋了
// 窗口自適應插件
const fitAddon = new FitAddon.FitAddon();
// 窗口尺寸變化時,終端尺寸自適應
window.onresize = () => {
fitAddon.fit();
};
this.term.loadAddon(fitAddon);
this.term.open(document.getElementById("terminal"));
this.term.focus();
// 自定義終端默認展示內容
this.writeDefaultInfo();
};
ws.onmessage = (event) => {
console.log("接收信息:", event.data);
let message = "\n" + JSON.parse(event.data).message; //根據後臺返回數據進行處理成對象形式進行顯示到頁面,如果不需要處理,需要直接
//將字符串轉換成 Blob對象
const blob = new Blob([message], {
type: "text/plain",
});
//將Blob 對象轉換成字符串
const reader = new FileReader();
reader.readAsText(blob, "utf-8");
reader.onload = (e) => {
// 可以根據返回值判斷使用何種顏色或者字體,不過返回值自帶了一些字體顏色
this.writeOfColor(reader.result, "0;", "37m");
};
};
ws.onerror = (event) => {
console.log("錯誤信息:", event);
if (wsTime) {
window.clearTimeout(wsTime);
wsTime = null;
}
wsTime = window.setTimeout(() => {
this.websocket();
}, 3000);
};
ws.onclose = (event) => {
console.log("已關閉連接:", event);
// if (wsTime) {
// window.clearTimeout(wsTime)
// wsTime = null
// }
// wsTime = window.setTimeout(() => {
// this.websocket()
// }, 3000)
};
} else {
console.log("瀏覽器不支持 WebSocket..");
}
// WebSocket end
},
},
});
</script>