vue+xterm.js+websocket实现的网页版终端权威指南

引言

        因为最近项目需要写一个网页版终端,然而网上资料很多,但发现相关配置和API都很少,而且官网文档也很难看懂,因此小编翻阅了核心的源码,实现了一版,在此分享给各位码农。本篇文章将尽可能全面的罗列出xterm的配置和API。

1. 环境搭建

本文将针对如下版本的依赖进行说明:

"xterm": "^5.3.0",

"xterm-addon-fit": "^0.8.0"

2. 初始化xterm.js

<template>
    <div class="terminalPage">
        <div class="terminal" ref="terminalDiv"></div>
    </div>
</template>

<script>
import * as xterm from 'xterm';
import 'xterm/css/xterm.css';
import { FitAddon } from 'xterm-addon-fit'; // 横向自适应

export default {
    name: 'terminal',
    data() {
        return {
            xterm: null,
            fitAddon: null,
            ws: null,
            commandBuffer: ''
        }
    },
    mounted() {
        this.initTerminal();
    },
    methods: {
        initTerminal() {
            this.xterm = new xterm.Terminal({
                rows: 30, // 可视窗口的行数
                cols: 80, // 可是窗口的列数
                cursorBlink: true, // 光标是否闪烁
                // 终端主题
                theme: {
                    foreground: '#ffffff',
                    background: '#000000'
                    cursor: '#ffffff',
                },
                fontFamily: 'Consolas, Courier, monospace',
                fontSize: 14,

            });
            this.xterm.open(this.$refs.terminalDiv);
            this.fitAddon = new FitAddon();
            this.xterm.loadAddon(this.fitAddon);
            this.fitAddon.fit();
            window.addEventListener('resize', () => {
                try {
                    this.fitAddon.fit();
                } catch (e) {
                    this.$message.error(e.message);
                }
            });

            this.xterm.write('Connecting \r\n');
            this.xterm.onData((data) => this.terminalOnData(data));
            this.xterm.onKey((event) => this.terminalOnKey(event));
        },
    }
}

</script>

3. 使用onData监听输入并在终端中实时显示

methods: {

    terminalOnData(data) {
         this.term.write(data);
         this.commandBuffer += data;
    }
}

4. 使用onKey处理键盘的快捷键操作

methods: {

    terminalOnKey(event) {
        const { domEvent } = event;
        const ctrlKey = this.checkCtrlKeyAllSystem(domEvent); // 是否按了Ctrl键

        // 回车键
        if (event.domEvent.key === 'Enter') {
            // 发送命令
            this.ws.send(this.commandBuffer);
            this.commandBuffer = '';

        // Tab键
        } else if (event.domEvent.key === 'Tab') {
             // tab补全...
        }

        // Backspace退格键或Delete删除键
        } else if (event.domEvent.key === 'Backspace' || event.domEvent.key === 'Delete') {
             // 在终端中模拟删除效果
             this.xterm.write('\b \b');

        // 上箭头
        } else if (event.domEvent.key === 'ArrowUp') {
             // 历史指令...
        }

        // 下箭头
        } else if (event.domEvent.key === 'ArrowDown') {
             // 历史指令...

        // Ctrl+C 快捷键
        } else if (ctrlKey && event.domEvent.key === 'c') {
             // ...
        }

        // Ctrl+Shift+A 快捷键
        } else if (ctrlKey && domEvent.shiftKey && event.domEvent.key === 'a') {
             // ...
        }

        // 其他按键与快捷键等处理...  
        // ...      

        } else {
             this.term.write(key)
        }
    }

    // 判断是否按了Ctrl键 - 兼容Mac和Win不同系统
    checkCtrlKeyAllSystem(domEvent) {
        const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
        const isPressCtrlKey = isMac ? domEvent.metaKey : domEvent.ctrlKey;
        return isPressCtrlKey;
    },
}

5. 使用WebSocket连接至服务器

mounted() {
    this.initSocket();
},

methods: {
    initSocket() {
      this.ws = new WebSocket('ws://192.168.1.1:8080/websocket/terminal')
      this.ws.onopen = this.socketOnOpen;
      this.ws.onmessage = this.socketOnMessage;
      this.ws.onclose = this.socketOnClose;
      this.ws.onerror = this.socketOnError;
    },

    socketOnOpen() {
       this.xterm.write('连接成功');
    },

    socketOnMessage(event) {
        console.log('收到消息', event.data);
        this.xterm.write(event.data);
    },

    socketOnClose() {
        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            this.xterm.write('\r\n\x1b[91mConnection closed');
        }
    },

    socketOnError(err) {
         console.error('WebSocket connection error:', err);
    },
}

6. xterm配置详解

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妍思码匠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值