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);
相关推荐
恋猫de小郭1 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅8 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅9 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端