最近工作有个需求,需要在web端实现一个远程连接终端操作的类似网页版xshell的实现。实现界面如下图。
需求:输入用户名密码,跟后台验证登陆,然后跟后端进行命令行通信。
开始做的时候,就选了xterm,然后照着一些demo写,结果遇到很多坑。
1.xterm版本不同,方法不同
xterm4.x应该是在2019月份就开始更新了,但现在网上用的大多数的版本还都是3.x。网上很多例子都是3.x的。开始没注意到,结果调用方法报undefined错误。一脸懵圈。
2.xterm没有详细的文档说明,有英文文档,也只有简单的几个例子。
官方文档地址:xtermjs.org/ 虽然文档不全,但是有还是比没有好。
3.我们自己的系统问题也挺多的。所以遇到一些问题,不知道是与现有的冲突,还是我没写对。总之探索的过程很煎熬。
文档
安装
npm install xterm //现在版本是4.8.1 安装xterm
npm install xterm-addon-fit // xterm 插件,让xterm适应外部样式
初始化
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
import '../node_modules/xterm/css/xterm.css' //如果你的xterm样式乱了,需要调整这个路径
//我后来是直接把这个css copy到项目目录下进行引用
//定义xterm的外观 具体看xterm文档
const term = new Terminal({
rendererType: 'canvas',
cursorBlink: true,
convertEol: true,
scrollback: 800,
row: 70,
theme: {
foreground: 'white',
background: '#181E29'
}})
const fitAddon = new FitAddon();
term.loadAddon(fitAddon);
fitAddon.fit();
term.open(document.getElementById('terminal')); //绑定dom节点
term.writeln('Connecting...');
原理
前端和后端的通信,使用的是WebSocket,后端连接服务器,我只负责前端部分,所以这里只列前端的方法。页面显示出控制台这个操作页面,使用的是xterm.js。整个工作流程就是:前端在xterm.js里面输入文字,通过socket和后端通信,后端把前端传过来的命令,通过ssh连接服务器,得到服务器返回的数据,通过socket传给前端,前端再显示出socket返回的内容。
之前走了一些弯路,网上很多帖子用socket.io-client这个插件,但是我装了以后,并不好用,后来发现xterm官网有现成的 ,xtermjs.org/docs/api/ad…
import { Terminal } from 'xterm';
import { AttachAddon } from 'xterm-addon-attach';
const term = new Terminal();
const socket = new WebSocket('wss://docker.example.com/containers/mycontainerid/attach/ws');
const attachAddon = new AttachAddon(socket);
// Attach the socket to term
term.loadAddon(attachAddon);
通信
let socket = new WebSocket('ws://192.168.3.155:8008/webssh');//地址
//输入内容 将内容传给服务器
term.onKey(e => {
// term.write(e.key);
// console.log(e.key)
socket.send(JSON.stringify({ "operate": "command", "command": e.key, module: "webssh" })); })
const operate = { onError: function (error) { //连接失败回调 term.write('Error: ' + error + '\r\n'); }, onConnect: function () { //连接成功回调 socket.send(JSON.stringify(option)) //连接成功的回调 }, onClose: function () { //连接关闭回调 term.write("\rconnection closed"); }, onData: function (data) { //收到数据时回调 term.write(data); term.focus() } }
if (window.WebSocket) { //如果支持websocket // this._connection = new WebSocket(endpoint); console.log("good!!!") } else { //否则报错 operate.onError('WebSocket Not Supported'); return; } //连接成功 socket.onopen = function () { operate.onConnect() }; socket.onmessage = function (evt) { let data = evt.data.toString(); //data = base64.decode(data); console.log("data", data) operate.onData(data); }; socket.onclose = function (evt) { operate.onClose(); }; }
demo
github:github.com/hourong88/x…
npm install
npm start
另外还有jquery版本demo
github:github.com/hourong88/x…
参考文章
-
xterm.js + vue + websocket实现终端功能(xterm 3.x+xterm 4.x)blog.csdn.net/weixin_3831…
-
node.js+react.js+xterm.js构建websshblog.csdn.net/weixin_3419…
allfirst_rank_ecpm_v3~pc_rank_v2-2-88666657.first_rank_ecpm_v3_pc_rank_v2&utm_term=xterm.js+react -
vue+xterm.js 实现Linux command界面blog.csdn.net/lxlmycsdnfr…
-
初窥Xterm.jsjuejin.cn/post/684490…