节点 SSH2 客户端连接会话
Posted
技术标签:
【中文标题】节点 SSH2 客户端连接会话【英文标题】:Node SSH2 client connection session 【发布时间】:2022-01-08 23:28:50 【问题描述】:我想使用 Node.js 设置与设备的 SSH 连接。 目标是连接并保持连接更长时间,而不是一遍又一遍地连接和断开连接。
我能够建立连接,但是当我的回调被多次调用时会出现问题。回调用于回答来自我的前端的 GET 请求,当回调多次触发时,响应标头被第二次填充,我得到一个错误。
有没有更优雅的方式来建立持久连接,同时避免多次回调?
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);
);
);
【问题讨论】:
【参考方案1】:问题是您正在对流发出的'data'
事件的数量做出假设。对于一般的流,你永远不应该做出这样的假设。
我建议始终对流进行防御性编码,就好像您一次可能会获得 1 个字节,或者您可能会在单个事件中获得您正在寻找的全部数据。
要解决此问题,您需要知道何时拥有所有数据,这完全取决于您正在执行的命令。对于许多命令,最有可能在发出'close'
事件以指示该流不再有输出(进程已退出)时。然而,对于一些长时间运行的进程,在远程进程的生命周期内发送多个请求,您需要找到一种方法来找到流输出中每个“响应”的结尾。
无论哪种方式,在执行回调之前,您都需要缓冲数据,直到看到“响应”结束。
【讨论】:
这是一个很好的观点。我必须确保解决这个问题。但目前的问题是我连接触发回调并结束或错误进行回调。这会导致函数被调用两次并且代码失败 那么只要确保你调用回调一次?为此,您可以使用布尔标志或包装回调以确保无论何时/何地调用它都只被调用一次,而无需在任何地方添加条件。以上是关于节点 SSH2 客户端连接会话的主要内容,如果未能解决你的问题,请参考以下文章