github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/utils/classes/exec-socket-xterm-adapter.js (about)

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