xterm.js结合websocket实现web ssh

xterm.js结合websocket实现web ssh

xterm.js的使用背景

实现一个web ssh来通过输入命令来控制k8s pod中的容器,支持/bin/bash/bin/sh

实现流程

前端只处理按键的发送,例如当想要输入ll命令来查看文件,当输入l的时候就通过ws连接向后端发送l的按键,再输入l就再发送l,输入回车就发送回车。监听键盘按下全部都通过xterm的onDate函数来监听。

前端终端的显示并不是前端控制的,而是通过后端返回的内容控制,例如当输入l的时候,前端并不使用xterm的write插入,而是通过ws将l发送给后端,后端通过ws返回l,前端监听ws的message来使用xterm的write插入。

xterm.js安装

yaml 复制代码
npm i xterm

xterm.js初始化

采用vue2来实现xterm.js的初始化

js 复制代码
import { Terminal } from 'xterm';
import Vue from 'vue';
class SelfTerminal extends Vue {
    term = null;
    mounted() {
        // 初始化终端
        this.initXterm();
    }
    initXterm() {
        let term = new Terminal({
            rendererType: 'canvas', // 渲染类型
            convertEol: true, // 启用时,光标将设置为下一行的开头
            disableStdin: false, // 是否应禁用输入
            cursorBlink: true, // 光标闪烁
            theme: {
                foreground: '#ECECEC', // 字体
                background: '#000000', // 背景色
                cursor: 'help', // 设置光标
                lineHeight: 20,
            },
        });
        this.term = term;
        // 发送消息
        this.terminalSendMessage();
    }
    terminalSendMessage() {
        const term = this.term;
        // 发送消息 键入消息
        term.onData((content) => {
            this.handleSocketSendMessage(content);
        });
    }
}

xterm.js渲染

通过xterm实例上的open命令为DOM绑定渲染终端

js 复制代码
<div class="terminalContainer">
    <div ref="terminal" class="xterm" />
</div>
this.term.open(this.$refs.terminal);

xterm.js常见插件介绍

xterm-addon-webgl

xterm-addon-webgl插件的作用是使用webGL来加速渲染,如果没使用该插件xterm生成的终端是通过DOM渲染的,如果使用该插件则通过canvas渲染。
xterm-addon-webgl插件可以在xterm初始化的时候添加,将DOM渲染改为webGL来加速渲染。

js 复制代码
const webglAddon = new WebglAddon();
term.loadAddon(webglAddon);

xterm-addon-fit

xterm-addon-fit插件的作用是自动调整终端的行数和列数来盛满父容器。

可以通过xterm-addon-fit插件来获取将终端盛满父容器,将xterm实例上的rows和cols返回给后端,后端用于设置终端的行数和列数,用来同步前端展示的行数列数和后端终端的一致。

如果前端和后端行数列数不一直的影响:例如在vim编辑状态,如果后端的行数少于前端的行数,vim进入编辑状态返回了首屏的内容,前端在终端上加载首屏内容,由于前端行数多于后端,就导致首屏的内容在前端的终端渲染撑不满。

需要注意的点是xterm-addon-fit插件需要在xterm调用了open方法后使用才会生效。

js 复制代码
import { FitAddon } from 'xterm-addon-fit';
const _this = this;
// 终端大小自适应屏幕插件
const fitAddon = new FitAddon();
this.term.loadAddon(fitAddon);
// xterm渲染
this.term.open(this.$refs.terminal);
// 大小自适应
fitAddon.fit();
// ws发送行数和列数给后端
_this.handleSocketSendMessage({ type: 'TERMINAL_RESIZE', row: _this.term.rows, col: _this.term.cols });
// 窗口大小改变时,触发xterm的resize方法使自适应
function resizeScreen() {
    fitAddon.fit();
    // ws发送行数和列数给后端
    _this.handleSocketSendMessage({ type: 'TERMINAL_RESIZE', row: _this.term.rows, col: _this.term.cols });
}
window.addEventListener('resize', resizeScreen);

xterm-addon-attach

xterm-addon-attach这个插件允许终端通过 WebSocket 与远程服务器进行通信,从而实现实时数据传输和命令执行。如果使用改插件则不用通过xterm的onData来向ws发送消息,也不用通过xterm的write插入内容,改插件会全部处理ws的发送和接收。

但是xterm-addon-attach发送的消息为按键的字符串,如果想要自定义ws发送的数据不能使用改插件,需要自己通过onData处理ws发送的数据。

注意:xterm-addon-attach 需要 xterm.js v4+

js 复制代码
import { AttachAddon } from 'xterm-addon-attach';
const socket = new WebSocket('ws://xxx');
const attachAddon = new AttachAddon(socket);
this.term.loadAddon(attachAddon);
相关推荐
web小白成长日记8 小时前
企业级 Vue3 + Element Plus 主题定制架构:从“能用”到“好用”的进阶之路
前端·架构
APIshop9 小时前
Python 爬虫获取 item_get_web —— 淘宝商品 SKU、详情图、券后价全流程解析
前端·爬虫·python
懒人村杂货铺9 小时前
✅ WebSocket 接口从本地开发到生产部署的关键步骤与常见问题
websocket
风送雨9 小时前
FastMCP 2.0 服务端开发教学文档(下)
服务器·前端·网络·人工智能·python·ai
XTTX1109 小时前
Vue3+Cesium教程(36)--动态设置降雨效果
前端·javascript·vue.js
LYFlied10 小时前
WebGPU与浏览器边缘智能:开启去中心化AI新纪元
前端·人工智能·大模型·去中心化·区块链
Setsuna_F_Seiei10 小时前
2025 年度总结:人生重要阶段的一年
前端·程序员·年终总结
model200510 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
han_11 小时前
从一道前端面试题,谈 JS 对象存储特点和运算符执行顺序
前端·javascript·面试
aPurpleBerry11 小时前
React 01 目录结构、tsx 语法
前端·react.js