最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 基于Express+xterm.js+ssh2的WebSSH

    正文概述 掘金(天空影)   2020-12-23   1081

    源文档地址:基于Express的WebSSH

    后端基于nodeexpressssh2websocket

    前端基于reactxterm.js

    1. 服务端

    1.1 下载npm

    yarn add express-ws ssh2 utf8
    

    1.2 服务端代码

    src/utils/createNewServer.ts

    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');
          }
    
          // 前端发送消息
          socket.on('message', function (data: any) {
            stream.write(data);
          });
    
          // 通过sh发送消息给前端
          stream.on('data', function (d: any) {
            socket.send(utf8.decode(d.toString('binary')));
    
            // 关闭连接
          }).on('close', function () {
            ssh.end();
          });
        })
    
        // 关闭连接
      }).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
      });
    }
    

    src/main.ts

    const express = require('express');
    const app = express();
    const expressWs = require('express-ws')(app);
    
    import { createNewServer } from './utils/createNewServer';
    
    
    app.get('/', function (req: any, res: any, next: any) {
      res.end();
    });
    
    app.ws('/', function (ws: any, req: any) {
      createNewServer({
        host: '192.168.2.94',
        username: 'megaium',
        password: 'Megaium!'
      }, ws)
    });
    
    app.listen(3000)
    

    2. 客户端

    2.1 客户端代码

    *.ts

    import React, { useEffect, useState } from 'react';
    import { Terminal } from 'xterm';
    import { WebLinksAddon } from 'xterm-addon-web-links';
    import { FitAddon } from 'xterm-addon-fit';
    
    import 'xterm/css/xterm.css';
    import styles from './index.less';
    
    const FontSize: number = 14;
    const Col = 80;
    
    const WebTerminal = () => {
      const [webTerminal, setWebTerminal] = useState<Terminal | null>(null);
      const [ws, setWs] = useState<WebSocket | null>(null);
    
      useEffect(() => {
        // 新增监听事件
        if (webTerminal && ws) {
          // 监听
          webTerminal.onKey(e => {
            const { key } = e;
            ws.send(key);
          });
    
          // ws监听
          ws.onmessage = e => {
            console.log(e);
    
            if (webTerminal) {
              if (typeof e.data === 'string') {
                webTerminal.write(e.data);
              } else {
                console.error('格式错误');
              }
            }
          };
        }
      }, [webTerminal, ws]);
    
      useEffect(() => {
        // 初始化终端
    
        const ele = document.getElementById('terminal');
        if (ele) {
          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();
          setWebTerminal(terminal);
        }
    
        // 初始化ws连接
        if (ws) ws.close();
    
        const socket = new WebSocket('ws://192.168.2.123:3000');
        socket.onopen = () => {
          socket.send('connect success');
        };
    
        setWs(socket);
      }, []);
    
      return <div id="terminal" className={styles.main} />;
    };
    
    export default WebTerminal;
    

    3. 效果

    基于Express+xterm.js+ssh2的WebSSH


    起源地下载网 » 基于Express+xterm.js+ssh2的WebSSH

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元