大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说xterm.js 前端终端库(React)「建议收藏」,希望您对编程的造诣更进一步.
官网:xtermjs.org/
npm install xterm
需求:打开控制台,弹出一个新的页面,页面显示终端,通过WebSocket与后端进行连接。
1、打开一个特定的页面。
import React from 'react';
import Terminal from '@/components/Terminal';
// ...
const redirectToTerminal = () => (
<Router> <Route path="/terminal/:url" components={Terminal} exact /> </Router>
);
if (window.location.href.includes('terminal')) {
return redirectToTerminal();
};
2、终端适应父元素的大小
按照官网的描述,是使用 xterm-addon-fit插件。
npm install xterm-addon-fit
以及官网描述的使用方式
import { Terminal } from 'xterm';
import { FitAddon } from 'xterm-addon-fit';
const term = new Terminal();
const fitAddon = new FitAddon();
term.loadAddon(fitAddon);
// Open the terminal in #terminal-container
term.open(document.getElementById('terminal-container'));
// Make the terminal's size and geometry fit the size of #terminal-container
fitAddon.fit();
后来又时间查看源码【源码】,返回了4个方法,分别是 activate(启动),dispose(销毁),fit(适应),proposeDimensions(获取尺寸)
3、终端进行websocket连接
官网也有一个插件可以使用 xterm-addon-attach
npm install xterm-addon-attach
以及官网描述的使用方式
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);
由于在自己使用时,在界面显示时出现了问题,后端返回的数据未经过处理在界面上显示了一次,然后处理过后的又显示了一次,就很尴尬。最后在代码中,我是没有使用的。
看了一下源码【源码】,总共也就两个方法,一个是 activate(启动),一个是dispose(销毁)在 activate 方法中 直接对返回的数据进行了初步的处理然后 terminal.write 了,我个人认为是这个原因导致的。
最后 Terminal.tsx 源码
import React, { useEffect } from 'react';
import 'xterm/css/xterm.css';
import { Terminal } from 'xterm';
import { useParams } from 'react-router';
import { AttachAddon } from 'xterm-addon-attach';
import { FitAddon } from 'xterm-addon-fit';
import cache from '@/utils/storage';
const TOKEN = 'token';
const action = (type: any, data?: any) => {
const action = Object.assign(
{
type: type
},
data
);
return JSON.stringify(action);
};
interface ParamsProps {
url: string;
}
export default function MidTerminal(): JSX.Element {
const params: ParamsProps = useParams();
// 添加https和http的支持
// wss://${window.location.hostname}:${window.location.port}
const socketUrl =
window.location.protocol.toLowerCase() === 'https:'
? `wss://x.x.x.x:xxxx/ws/terminal?${params.url}`
: `ws://x.x.x.x:xxxx/ws/terminal?${params.url}`;
useEffect(() => {
const socket = new WebSocket(socketUrl, cache.getLocal(TOKEN));
const terminal = new Terminal({
cursorStyle: 'underline',
cursorBlink: true,
theme: {
foreground: '#dddddd',
cursor: 'gray'
},
windowsMode: true
});
const fitAddon = new FitAddon();
terminal.loadAddon(fitAddon);
const terminalDom = document.getElementById('terminal-container');
terminal.open(terminalDom as HTMLElement);
fitAddon.fit();
socket.onopen = () => {
socket.send(action('TERMINAL_INIT'));
socket.send(action('TERMINAL_READY'));
socket.send(
action('TERMINAL_RESIZE', {
columns: fitAddon.proposeDimensions().cols,
rows: fitAddon.proposeDimensions().rows
})
);
terminal.write('Welcome to terminal! \r\n$');
};
socket.onclose = () => {
terminal.write('Bye Bye! \r\n$');
};
socket.onerror = () => {
terminal.write('Something errors \r\n$');
};
terminal.onData((e: string) => {
socket.send(
action('TERMINAL_COMMAND', {
command: e
})
);
});
socket.onmessage = (e: MessageEvent<any>) => {
const data = JSON.parse(e?.data);
if (data?.type == 'TERMINAL_PRINT') {
terminal.write(data.text);
}
};
return () => {
socket.close();
terminal.dispose();
};
}, []);
return (
<div id="terminal-container" style={{ width: '100%', height: '100%' }} ></div>
);
}
xterm插件前前后后搞了近一个星期,看了源码还有很多插件没有使用过,这次也只是使用了最基础的两个,以后有机会的话会尝试一下其他的插件的。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13546.html