github.com/hernad/nomad@v1.6.112/ui/app/utils/classes/exec-socket-xterm-adapter.js (about)

     1  /**
     2   * Copyright (c) HashiCorp, Inc.
     3   * SPDX-License-Identifier: MPL-2.0
     4   */
     5  
     6  const ANSI_UI_GRAY_400 = '\x1b[38;2;142;150;163m';
     7  
     8  import { base64DecodeString, base64EncodeString } from 'nomad-ui/utils/encode';
     9  
    10  export const HEARTBEAT_INTERVAL = 10000; // ten seconds
    11  
    12  export default class ExecSocketXtermAdapter {
    13    constructor(terminal, socket, token) {
    14      this.terminal = terminal;
    15      this.socket = socket;
    16      this.token = token;
    17  
    18      socket.onopen = () => {
    19        this.sendWsHandshake();
    20        this.sendTtySize();
    21        this.startHeartbeat();
    22  
    23        terminal.onData((data) => {
    24          this.handleData(data);
    25        });
    26      };
    27  
    28      socket.onmessage = (e) => {
    29        let json = JSON.parse(e.data);
    30  
    31        // stderr messages will not be produced as the socket is opened with the tty flag
    32        if (json.stdout && json.stdout.data) {
    33          terminal.write(base64DecodeString(json.stdout.data));
    34        }
    35      };
    36  
    37      socket.onclose = () => {
    38        this.stopHeartbeat();
    39        this.terminal.writeln('');
    40        this.terminal.write(ANSI_UI_GRAY_400);
    41        this.terminal.writeln('The connection has closed.');
    42        // Issue to add interpretation of close events: https://github.com/hernad/nomad/issues/7464
    43      };
    44  
    45      terminal.resized = () => {
    46        this.sendTtySize();
    47      };
    48    }
    49  
    50    sendTtySize() {
    51      this.socket.send(
    52        JSON.stringify({
    53          tty_size: { width: this.terminal.cols, height: this.terminal.rows },
    54        })
    55      );
    56    }
    57  
    58    sendWsHandshake() {
    59      this.socket.send(
    60        JSON.stringify({ version: 1, auth_token: this.token || '' })
    61      );
    62    }
    63  
    64    startHeartbeat() {
    65      this.heartbeatTimer = setInterval(() => {
    66        this.socket.send(JSON.stringify({}));
    67      }, HEARTBEAT_INTERVAL);
    68    }
    69  
    70    stopHeartbeat() {
    71      clearInterval(this.heartbeatTimer);
    72    }
    73  
    74    handleData(data) {
    75      this.socket.send(
    76        JSON.stringify({ stdin: { data: base64EncodeString(data) } })
    77      );
    78    }
    79  }