react?express實現(xiàn)webssh?demo解析
正文
下面是一個簡單的 WebSSH Demo,實現(xiàn)了通過瀏覽器連接 SSH 服務(wù)器并進(jìn)行交互的功能。
實現(xiàn) WebSSH 的基本思路
WebSSH 可以分成以下幾個模塊:
- 前端界面:使用 xterm.js 實現(xiàn)一個基于瀏覽器的終端界面。
- WebSocket 連接:使用 WebSocket 連接連接 WebSSH 服務(wù)器后端。
- SSH 連接:使用 ssh2.js 庫連接 SSH 服務(wù)器,然后在 WebSocket 和 SSH 之間建立一個雙向通訊。
實現(xiàn) Demo 的代碼
服務(wù)器端代碼
服務(wù)器端代碼使用 Node.js 和 WebSocket 模塊實現(xiàn),主要用于連接到遠(yuǎn)程 SSH 服務(wù)器并與前端建立 WebSocket 連接。
const SSHClient = require('ssh2').Client;
const utf8 = require('utf8');
export const createNewServer = (machineConfig: any, socket: any) => {
const ssh = new SSHClient();
const { host, username, password } = machineConfig;
// 連接成功
ssh.on('ready', function () {
socket.send('\r\n*** SSH CONNECTION SUCCESS ***\r\n');
ssh.shell(function (err: any, stream: any) {
// 出錯
if (err) {
return socket.send('\r\n*** SSH SHELL ERROR: ' + err.message + ' ***\r\n');
}
// 前端發(fā)送消息
socket.on('message', function (data: any) {
stream.write(data);
});
// 通過sh發(fā)送消息給前端
stream.on('data', function (d: any) {
socket.send(utf8.decode(d.toString('binary')));
// 關(guān)閉連接
}).on('close', function () {
ssh.end();
});
})
// 關(guān)閉連接
}).on('close', function () {
socket.send('\r\n*** SSH CONNECTION CLOSED ***\r\n');
// 連接錯誤
}).on('error', function (err: any) {
socket.send('\r\n*** SSH CONNECTION ERROR: ' + err.message + ' ***\r\n');
// 連接
}).connect({
port: 22,
host,
username,
password
});
}
前端代碼
前端代碼主要包括一個包裝 xterm.js 的 React 組件和一些 WebSockets 相關(guān)的代碼。
import React, { useEffect, useRef } from 'react';
import { Terminal } from 'xterm';
import { WebLinksAddon } from 'xterm-addon-web-links';
import { FitAddon } from 'xterm-addon-fit';
import 'xterm/css/xterm.css';
const FontSize = 14;
const Col = 80;
const WebTerminal = () => {
const webTerminal = useRef(null);
const ws = useRef(null);
useEffect(() => {
// 初始化終端
const ele = document.getElementById('terminal');
if (ele && !webTerminal.current) {
const height = ele.clientHeight;
// 初始化
const terminal = new Terminal({
cursorBlink: true,
cols: Col,
rows: Math.ceil(height / FontSize),
});
// 輔助
const fitAddon = new FitAddon();
terminal.loadAddon(new WebLinksAddon());
terminal.loadAddon(fitAddon);
terminal.open(ele);
terminal.write('Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ');
fitAddon.fit();
webTerminal.current = terminal;
}
// 初始化ws連接
if (ws.current) ws.current.close();
const socket = new WebSocket('ws://localhost:3001');
socket.onopen = () => {
socket.send('connect success');
};
ws.current = socket;
}, []);
useEffect(() => {
// 新增監(jiān)聽事件
const terminal = webTerminal.current;
const socket = ws.current;
if (terminal && socket) {
// 監(jiān)聽
terminal.onKey(e => {
const { key } = e;
socket.send(key);
});
// ws監(jiān)聽
socket.onmessage = e => {
console.log(e);
if (typeof e.data === 'string') {
terminal.write(e.data);
} else {
console.error('格式錯誤');
}
};
}
}, []);
return <div id="terminal" style={{ backgroundColor: '#000', width: '100vw', height: '100vh' }}/>;
};
export default WebTerminal;
WebSSH 組件借助 Hooks 特性進(jìn)行 WebSocket 和 xterm.js 的初始化。具體來說,這個組件使用了 useEffect Hook 在組件掛載時完成以下工作:
- 初始化 Terminal 組件。
- 初始化 WebSocket 連接。
- 為 Terminal 組件綁定輸入事件和 WebSocket 發(fā)送數(shù)據(jù)的邏輯。
在 React 應(yīng)用中使用 WebSSH 組件
你需要在你的 React的index.js 文件中引入 WebSSH 組件,并在你的應(yīng)用中渲染它:
import WebSSH from './components/WebSSH';
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<WebSSH />,
document.getElementById('root')
);
效果

編輯
總結(jié)
在本篇博客中,我們學(xué)習(xí)了如何使用 xterm.js、WebSocket 和 ssh2.js 庫構(gòu)建一個 WebSSH 應(yīng)用程序。我們創(chuàng)建了一個簡單的 Demo 來演示該過程。
完整代碼參考
GitHub - judithhuang/webssh-demo
以上就是react express實現(xiàn)webssh demo解析的詳細(xì)內(nèi)容,更多關(guān)于react express實現(xiàn)webssh的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React Native實現(xiàn)進(jìn)度條彈框的示例代碼
本篇文章主要介紹了React Native實現(xiàn)進(jìn)度條彈框的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07
React中useCallback useMemo到底該怎么用
在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時,默認(rèn)情況下整個組件都會重新渲染。換句話說,如果組件中的任何值更新,整個組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender2023-02-02
Zustand介紹與使用 React狀態(tài)管理工具的解決方案
本文主要介紹了Zustand,一種基于React的狀態(tài)管理庫,Zustand以簡潔易用、靈活性高及最小化原則等特點脫穎而出,旨在提供簡單而強(qiáng)大的狀態(tài)管理功能2024-10-10
VSCode配置react開發(fā)環(huán)境的步驟
本篇文章主要介紹了VSCode配置react開發(fā)環(huán)境的步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12
react中通過props實現(xiàn)父子組件間通信的使用示例
在React中,父組件可以通過props屬性向子組件傳遞數(shù)據(jù),子組件可以通過props屬性接收父組件傳遞過來的數(shù)據(jù),本文就來介紹一下如何實現(xiàn),感興趣的可以了解一下2023-10-10
react-router中Link標(biāo)簽和a標(biāo)簽有什么區(qū)別
本文主要介紹了react-router中Link標(biāo)簽和a標(biāo)簽有什么區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-06-06
詳解使用WebPack搭建React開發(fā)環(huán)境
這篇文章主要介紹了詳解使用WebPack搭建React開發(fā)環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
react koa rematch 如何打造一套服務(wù)端渲染架子
這篇文章主要介紹了react koa rematch 如何打造一套服務(wù)端渲染架子,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

