简体   繁体   English

节点SSH2客户端连接session

[英]Node SSH2 client connection session

I want to setup an SSH-connection to a device using Node.js.我想使用 Node.js 设置与设备的 SSH 连接。 The goal is to connect and keep the connection for a longer time, instead of connecting and disconnecting over and over again.目标是连接并保持连接更长时间,而不是一遍又一遍地连接和断开连接。

I was able to setup a connection but a problem arises when my callbacks are getting called multiple times.我能够建立连接,但是当我的回调被多次调用时会出现问题。 The callbacks are used to answer GET-requests from my frontend and when the callback fire multiple time the response header gets filled a second time and I get an error.回调用于回答来自我的前端的 GET 请求,当回调多次触发时,响应 header 被第二次填充,我得到一个错误。

Is there a more elegant way to build up a long lasting connection while avoiding multiple callbacks?有没有更优雅的方式来建立持久的连接,同时避免多次回调?

const { Client } = require('ssh2');

var connection;
var connEstablished = false;


var connect = (callback) => {
    const conn = new Client();
    conn.on('ready', () => {
        callback(null, true);
        connection = conn;
        connEstablished = true;
        console.log("Connection ready");
    }).connect({
        host: '192.168.1.1',
        port: 22,
        username: 'pi',
        password: 'raspberry',
        readyTimeout: 2000,
        keepaliveInterval: 500
    });
    conn.on('end', () => {
        callback(null, false);
        connection = null;
        connEstablished = false;
        console.log("Connection end");
    })
    conn.on('error', (error) => {
        callback(error, false);
        connection = null;
        connEstablished = false;
        console.error("SSH Client Error: ", JSON.stringify(error));
    })
};

var disconnect = () => {
    if (!connEstablished) {
        return;
    }

    connection.end();
}

var command = (command) => {
    if (!connEstablished) {
        return;
    }

    connection.exec(command, (err, stream) => {
        if (err) {
            callback(err);
            return;
        }
        stream.on('data', (data) => {
            callback(null, data);
        }).stderr.on('data', (data) => {
            callback(null, data);
        });
    });
}

The problem is that you're making assumptions about the number of 'data' events emitted by a stream.问题是您正在假设 stream 发出的'data'事件的数量。 For streams in general, you should never make such assumptions.对于一般的流,你永远不应该做出这样的假设。

I suggest always coding defensively for streams as if you may get 1 byte at a time or you may get the entirety of the data you're looking for in a single event.我建议始终对流进行防御性编码,就好像您一次可能获得 1 个字节,或者您可能会在单个事件中获得您正在寻找的全部数据。

To fix this problem you will need to know when you have all of the data, which is entirely dependent upon the command(s) you are executing.要解决此问题,您需要知道何时拥有所有数据,这完全取决于您正在执行的命令。 For many commands it's most likely when the 'close' event is emitted to indicate there will be no more output for that stream (the process has exited).对于许多命令,最有可能发出'close'事件以指示该 stream 将不再有 output(进程已退出)。 However for some long-running processes where you send multiple requests over the lifetime of the remote process, you will need to find a way to find the end of each "response" in the stream's output.但是,对于一些在远程进程的生命周期内发送多个请求的长时间运行的进程,您需要找到一种方法来找到流的 output 中每个“响应”的结尾。

Either way, you will need to buffer the data until you see the end of the "response" before you execute your callback.无论哪种方式,在执行回调之前,您都需要缓冲数据,直到看到“响应”结束。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM