美文网首页
webssh-xterm.js的简单使用

webssh-xterm.js的简单使用

作者: 家里有棵核桃树 | 来源:发表于2021-03-26 10:38 被阅读0次

    xterm是一个使用TypeScript编写的前端终端组件。

    1、demo主要介绍

    本文demo主要实现一个页面一个webssh窗口,前端部分主要利用xterm通过原生ws和后端通信,后端部分使用nodejs+utf8+ws+ssh2

    页面效果
    简要流程

    2、前端实现

    基于vue项目,前端主要依赖包:xterm xterm-addon-fit,使用前请install。

    <template>
      <div id="xterm"/>
    </template>
    
    <script>
    import 'xterm/css/xterm.css'
    import { Terminal } from 'xterm';
    import { FitAddon } from "xterm-addon-fit";
    
    export default {
      name: 'WebShell',
      data() {
        return {
          socketURI: 'ws://localhost:2000/'
        }
      },
      mounted() {
        this.initSocket()
      },
      beforeDestroy() {
        this.socket.close()
        this.term && this.term.dispose()
      },
      methods: {
        initTerm() {
          let element = document.getElementById('xterm');
          // 设置了cols或者fitAddon.fit(); 当一行字符超过80个过会替换现在的内容,否则换行
          const term = new Terminal({
            cursorBlink: true, // 关标闪烁
            cursorStyle: "underline", // 光标样式 'block' | 'underline' | 'bar'
            scrollback: 100, // 当行的滚动超过初始值时保留的行视窗,越大回滚能看的内容越多,
          });
          this.term = term;
          const fitAddon = new FitAddon();
          this.term.loadAddon(fitAddon);
          this.fitAddon = fitAddon;
          term.open(element);
          // 自适应大小(使终端的尺寸和几何尺寸适合于终端容器的尺寸),初始化的时候宽高都是对的
          fitAddon.fit();
          term.focus();
    
          this.term.onData(data =>  {
            this.socket.send(data);
          });
    
          window.addEventListener('resize', this.resizeTerm);
        },
        getColsAndRows(element) {
          // 暂时不用
          element = element || document.getElementById('xterm');
          return {
            rows: parseInt((element.clientHeight - 0) / 18),
            cols: 10 // parseInt(element.clientWidth / 8)
          };
        },
        resizeTerm() {
          this.fitAddon.fit();
          this.term.scrollToBottom();
        },
        initSocket() {
          this.socket = new WebSocket(this.socketURI);
          this.socketOnClose();
          this.socketOnOpen();
          this.socketOnError();
          this.socketOnMessage();
        },
        socketOnOpen() {
          this.socket.onopen = () => {
            // 连接成功后
            this.initTerm()
          }
        },
        socketOnMessage() {
          this.socket.onmessage = (event) => {
            // 接收推送的消息
            this.term.write(event.data.toString());
          }
        },
        socketOnClose() {
          this.socket.onclose = () => {
            console.log('close socket')
          }
        },
        socketOnError() {
          this.socket.onerror = () => {
            console.log('socket error')
          }
        }
      }
    }
    </script>
    
    <style scoped>
    #xterm {
      padding: 15px 0;
    }
    </style>
    

    3、后端实现

    前端主要依赖包:utf8 ssh2 ws,使用前请install。
    ssh2用来实现nodejs和服务器进行连接和通信。
    utf8用来实现服务器返回的命令执行结果解码。
    ws用来实现后端和前端ws全双工通信。

    /**用来实现单个webssh功能**/
    const utf8 = require("utf8");
    const SSHClient = require("ssh2").Client;
    const Server = require("ws").Server;
    const wss = new Server({
      port: 2000
    });
    
    const serverInfo = {
      host: '192.168.18.141',
      port: 22,
      username: 'root',
      password: '密码不告诉你.'
    };
    
    function createSocket(ws) {
      const ssh = new SSHClient();
      ssh
        .on("ready", function () {
          ws.send("\r\n*** SSH CONNECTION ESTABLISHED ***\r\n");
          ssh.shell(function (err, stream) {
            if (err) {
              return ws.emit("\r\n*** SSH SHELL ERROR: " + err.message + " ***\r\n");
            }
            ws.on("message", function (data) {
              stream.write(data);
            });
            ws.on("close", function () {
              console.log("close websocket。");
              ssh.end();
            });
            stream
              .on("data", function (d) {
                let data = utf8.decode(d.toString("binary"));
                ws.send(data);
              })
              .on("close", function () {
                ssh.end();
              });
          });
        })
        .on("close", function () {
          ws.close();
        })
        .on("error", function (err) {
          console.log("\r\n*** SSH CONNECTION ERROR: " + err.message + " ***\r\n");
          ws.close();
        })
        .connect(serverInfo);
    }
    
    wss.on("connection", function (ws) {
      createSocket(ws);
    });
    

    4、遗留问题

    1、浏览器resize后,webshell窗口宽高自适应、命令显示的问题;
    2、设置了cols或者fitAddon.fit(); 当一行字符超过80个后,会替换现在的内容问题。

    5、友情链接

    相关文章

      网友评论

          本文标题:webssh-xterm.js的简单使用

          本文链接:https://www.haomeiwen.com/subject/snfjhltx.html