萬(wàn)萬(wàn)沒(méi)想到,用瀏覽器打開(kāi)終端竟這么容易實(shí)現(xiàn)
共 7092字,需瀏覽 15分鐘
·
2024-05-25 23:55
大廠技術(shù) 高級(jí)前端 Node進(jìn)階
點(diǎn)擊上方 程序員成長(zhǎng)指北,關(guān)注公眾號(hào)
回復(fù)1,加入高級(jí)Node交流群
前言
你所追求的事物,所做的每一件事情,都有它存在的意義
說(shuō)到用網(wǎng)頁(yè)打開(kāi)終端,相信大多數(shù)人都使用過(guò),但是應(yīng)該也沒(méi)幾個(gè)人去認(rèn)真研究過(guò)??。自己也是因工作需要,于是對(duì)其進(jìn)行了一番探索。
如果你有用過(guò)云服務(wù)器,肯定對(duì)這個(gè)就更熟悉了,比如阿里云的Workbench遠(yuǎn)程連接。它提供給我們的服務(wù)便利性、用戶體驗(yàn)還是相當(dāng)不錯(cuò)的,讓我們和實(shí)際的機(jī)器通過(guò)網(wǎng)絡(luò)聯(lián)通了。
除此之外,瀏覽器上能運(yùn)行的東西還有很多,如:云文檔、云軟件、云IDE、云儲(chǔ)存、云函數(shù)、云調(diào)用、云編輯器 等等......
下面我們來(lái)做個(gè)小任務(wù):用網(wǎng)頁(yè)打開(kāi)終端,然后在終端輸入small_cat指令后,在終端輸出一群小貓咪??。
先一睹為快
快速實(shí)現(xiàn)(僅需兩步?? + 瀏覽器訪問(wèn))
已有很成熟的組件庫(kù)基于xterm.js來(lái)實(shí)現(xiàn)網(wǎng)頁(yè)終端,比如webssh(More Real-world Uses[1]),僅需兩步就可以在網(wǎng)頁(yè)連接你的服務(wù)器了。有木有很驚喜??
1. 執(zhí)行pip install webssh,安裝webssh
首先要確定電腦安裝了Python,且版本為2.7/3.4+
但實(shí)際上還是使用了python3(用pythond+pip安裝時(shí)報(bào)錯(cuò)了,可能是Python和pip版本不匹配)。
如果你使用的mac,可以通過(guò)命令查看是否已存在python3,如下:
python2 --version
-> Python 2.7.16
python3 --version 或者 /usr/bin/python3 --version
-> Python 3.9.5
確定有python3之后可以直接執(zhí)行(如有錯(cuò)誤可再升級(jí)pip):
python3 -m pip install webssh 或者 pip3 install webssh
# 如果pip報(bào)錯(cuò),根據(jù)終端提示升級(jí)pip,執(zhí)行:
sudo /usr/bin/python3 -m pip install --upgrade pip
// 再重新安裝即可
sudo /usr/bin/python3 -m pip install webssh
2. 啟動(dòng)webssh服務(wù)
在終端輸入wssh即可在本地打開(kāi)瀏覽器訪問(wèn)了。
(當(dāng)然,運(yùn)行wssh會(huì)占用進(jìn)程,如果是部署到生產(chǎn)環(huán)境,需要使其在后臺(tái)運(yùn)行,并開(kāi)啟進(jìn)程守護(hù))
更多使用可參考webssh使用:github.com/huashengdun…[2]
3. 貓咪要怎樣畫(huà)?
回答可能會(huì)讓你大跌眼鏡??----答案是使用console??,我們可以使用console輸出字符圖片,也可以使用console輸出背景圖案(nodejs的console不支持輸出背景圖)。(當(dāng)然也可以使用echo, 總之都是用shell去執(zhí)行的腳本。)
到此,這個(gè)小任務(wù)就已完成了。
當(dāng)然,如果你是對(duì)技術(shù)比較有追求的小伙伴,想自己實(shí)現(xiàn)擴(kuò)展一些功能的話,也是沒(méi)問(wèn)題的。請(qǐng)看下面:
親自動(dòng)手實(shí)現(xiàn)
經(jīng)了解發(fā)現(xiàn),瀏覽器打開(kāi)終端的解決方案,大部分使用的xterm.js,它被 VS Code、Hyper 和 Theia 等流行項(xiàng)目使用。除了提供基本的功能,還提供了很多終端相關(guān)的插件。下面我們一起來(lái)使用它,實(shí)現(xiàn)自己的網(wǎng)頁(yè)終端。
1. 根據(jù)官方文檔安裝運(yùn)行\(zhòng)[xtermjs文檔地址\][3]
安裝:npm install xterm
直接在頁(yè)面中使用:
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
<!-- 也可以直接使用使用xterm的cdn靜態(tài)資源 -->
<script src="node_modules/xterm/lib/xterm.js"></script>
</head>
<body>
<div id="terminal"></div>
<script>
var term = new Terminal();
term.open(document.getElementById('terminal'));
term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
</script>
</body>
</html>
2.在客服端無(wú)法輸入字符
運(yùn)行后,發(fā)現(xiàn)無(wú)法在瀏覽器終端輸入任何字符。查找文檔后發(fā)現(xiàn)需要監(jiān)聽(tīng)每次的輸入:
term.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ')
// 需要在腳本下增加:
term.onData((value)=>{
term.write(value)
})
3.按刪除鍵無(wú)效,回車時(shí)光標(biāo)到了第一個(gè)字符
再次嘗試,發(fā)現(xiàn)可以輸入了,但是無(wú)法刪除已輸入的字符,繼續(xù)查文檔[4],發(fā)現(xiàn)是編碼問(wèn)題,無(wú)法識(shí)別刪除等鍵。如文檔所說(shuō),需使用node-pty來(lái)編譯輸入,它是基于 Node.js 的解決方案。
原理梳理(簡(jiǎn)概)
實(shí)現(xiàn)的邏輯是:客戶端的任何輸入指令 ==> 通過(guò)
websocket傳入到后端 ==> 在后端虛擬終端中編譯后 ==> 再將結(jié)果通過(guò)websocket返回給客戶端。
4.服務(wù)端虛擬終端(接收和轉(zhuǎn)換來(lái)自客服端的輸入)
瀏覽器端的具體實(shí)現(xiàn)(完整):
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="node_modules/xterm/css/xterm.css" />
<script src="node_modules/xterm/lib/xterm.js"></script>
<script src="https://www.unpkg.com/[email protected]/dayjs.min.js"></script>
<script src="https://www.unpkg.com/[email protected]/lib/xterm-addon-attach.js"></script>
</head>
<body>
<div id="terminal"></div>
<script>
var term = new Terminal();
term.open(document.getElementById('terminal'));
term.focus()
const socketURL = "ws://127.0.0.1:3030/socket";
const ws = new WebSocket(socketURL);
attachAddon = new AttachAddon.AttachAddon(ws);
term.loadAddon(attachAddon);
</script>
</body>
</html>
<!-- copy后可直接在本地嘗試使用 -->
服務(wù)端的具體實(shí)現(xiàn)(完整):
#!/usr/bin/env node
var express = require('express');
var app = express();
const pty = require("node-pty");
require('express-ws')(app);
const os = require("os");
const shell = os.platform() === "win32" ? "powershell.exe" : "bash";
app.ws("/socket", (ws, req) => {
console.log('websocket連接成功了')
// 每次連接的時(shí)候都要生成一次term。否則在客服端刷新頁(yè)面時(shí),服務(wù)端的term就會(huì)失去連接
// 虛擬終端(接收和轉(zhuǎn)換輸入)
const term = pty.spawn(shell, ["--login"], {
name: "xterm",
cols: 50,
rows: 24,
cwd: process.env.HOME,
env: process.env,
});
ws.on("open", (data) => {
console.log('open data===', data)
});
term.on("data", function (data) {
console.log('發(fā)送給客服端的數(shù)據(jù)===', data)
ws.send(data);
});
ws.on("message", (data) => {
console.log('接收客服端的數(shù)據(jù)===', data)
term.write(data);
});
ws.on("close", function () {
term.kill();
});
});
app.listen(3030);
// copy后可直接在本地嘗試使用
需要注意的是:客戶端每次連接服務(wù)端的時(shí)候都要生成一次term,因此在socket每次連接時(shí)都需要初始化一次。否則在客服端重新刷新頁(yè)面時(shí),服務(wù)端的term就會(huì)失去連接
目前,我們已實(shí)現(xiàn)了網(wǎng)頁(yè)終端的基本功能,官網(wǎng)還提供了很多有意思的插件,有興趣的小伙伴可以去嘗試喲!(More Real-world Uses[5])
文章主體內(nèi)容已完成,后續(xù)會(huì)繼續(xù)補(bǔ)充一些關(guān)于linux命名行操作、vim快捷操作的相關(guān)內(nèi)容。感興趣的同學(xué)可以先加個(gè)收藏(Ctrl + D 或 command + D),以備不時(shí)之需。
最后
如果我們?cè)谟龅侥承﹩?wèn)題沒(méi)有完整的思路時(shí),也不妨先嘗試下去實(shí)現(xiàn)。在實(shí)現(xiàn)的過(guò)程中再去尋找方法、總結(jié)經(jīng)驗(yàn)。而不應(yīng)該沒(méi)有任何嘗試就放棄實(shí)現(xiàn)或者認(rèn)為不可能實(shí)現(xiàn)。
如果覺(jué)得有幫助,不妨點(diǎn)贊、關(guān)注支持一下。如文章有不足之處、疑問(wèn)或建議,希望能在下方???? 留言,非常感謝。
作者:
tager
相關(guān)文章地址:`https://juejin.cn/user/4353721776234743/posts`[6]
https://xtermjs.org/: https://xtermjs.org/
[2]https://github.com/huashengdun/webssh: https://github.com/huashengdun/webssh
[3]https://xtermjs.org/: https://xtermjs.org/
[4]https://xtermjs.org/docs/guides/encoding/: https://xtermjs.org/docs/guides/encoding/
[5]https://xtermjs.org/: https://xtermjs.org/
[6]https://juejin.cn/user/4353721776234743/posts: https://juejin.cn/user/4353721776234743/posts
Node 社群
我組建了一個(gè)氛圍特別好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你對(duì)Node.js學(xué)習(xí)感興趣的話(后續(xù)有計(jì)劃也可以),我們可以一起進(jìn)行Node.js相關(guān)的交流、學(xué)習(xí)、共建。下方加 考拉 好友回復(fù)「Node」即可。
“分享、點(diǎn)贊、在看” 支持一下
