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);
相关推荐
一个专注写代码的程序媛34 分钟前
vue组件间通信
前端·javascript·vue.js
一笑code44 分钟前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员1 小时前
layui时间范围
前端·javascript·layui
NoneCoder1 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19701 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端
烛阴1 小时前
面试必考!一招教你区分JavaScript静态函数和普通函数,快收藏!
前端·javascript
GetcharZp1 小时前
xterm.js 终端神器到底有多强?用了才知道!
前端·后端·go
JiangJiang1 小时前
🚀 React 弹窗还能这样写?手撸一个高质量 Modal 玩起来!
前端·javascript·react.js
吃炸鸡的前端2 小时前
el-transfer穿梭框数据量过大的解决方案
前端·javascript
高德开放平台2 小时前
文末有奖|高德MCP 2.0 出行领域首发打通大模型与高德地图APP互联
前端