ssh2 подключается к нескольким серверам и получает выходные данные nodejs

Я использую модуль ssh2 nodejs для подключения к приложению UNIX и запуска сценария, и он работает успешно. Теперь я хочу подключиться к нескольким серверам один за другим, получить результат и сохранить его. Когда я пытаюсь использовать цикл for для передачи серверов один за другим из json в качестве входных данных для ssh2, цикл for завершается намного быстрее, чем блок, который должен получать выходные данные с сервера. Это также вызывает у меня ошибку рукопожатия. Пожалуйста, помогите

Вот код

inc_cron.schedule("*/20 * * * * *", function(id) {    
        });

//inc_cron.js

var cronFunction = function(inputStr) { 
                  if(appNames['applications'].length>0){ 
                                for (i = 0; i < appNames["applications"].length; i++) {  
                                  getDataFromServer(appNames["applications"][i].Name,appNames["applications"][i].hostname, appNames["applications"][i].username, appNames["applications"][i].password, appNames["applications"][i].log_path, function(err, data) { 
                                                if(err) {
                                                  logger.info("Error is in cronFunction = ", err);
                                                } else if(data) { 
                                                                output_data +=data;   
                                                }  ssh.close_second();
                                  }); 
                                } 
                }  
}

var getDataFromServer = function(Name,hostname, username, password, log_path, cb) { 
  ssh.close_second();
  ssh.connect_second({
    host: hostname,
    username: username,
    password: password
  }, function(err) {
    if(err) {
      logger.error('Err: ', err);
    } else {  
                                ssh.sftp("",'grep -o "ERROR" '+log_path+'.log.'+yr+'-'+mnth+'-* | wc -l', function(err, data) {
                                                      cb(err, data); 
                                });     }   });  }


//connect.js

SSHConnection.prototype.sftp = function(type, path,  cb) {
  var self = this;
  var log_data = '';
  self.connection2.exec(path +' ' + type,  { pty: true }, function(err, stream) {
                if (err) {
      logger.log('SECOND :: exec error: ' + err); 
    }
                stream.on('end', function() {
      self.connection2.end(); // close parent (and this) connection
    }).on('data', function(data) {
      logger.info(data.toString());
    });
                  }); 
};

person Sshastry    schedule 12.01.2017    source источник
comment
Можете ли вы показать нам свой код, который у вас есть, пожалуйста?   -  person Holger Will    schedule 12.01.2017
comment
@HolgerWill Я добавил код сейчас...   -  person Sshastry    schedule 12.01.2017


Ответы (2)


Не наблюдая за своим кодом, обязательно правильно обработайте асинхронную проблему с ssh2... используйте фабрику обещаний.

person Mech45    schedule 12.01.2017
comment
Пакет node-ssh, вероятно, является лучшим подходом для использования этой библиотеки с промисами. - person austin_ce; 12.09.2018

Один из способов сделать это — использовать асинхронное ожидание es7. Для этого вам нужно переписать функцию getDataFromServer, чтобы она возвращала обещание:

var getDataFromServer = function(Name,hostname, username, password, log_path, cb) { 
    return new Promise(function(resolve,reject){
        ssh.close_second();
        sh.connect_second({
            host: hostname,
            username: username,
            password: password
        },function(err) {
            if(err){
                reject(err)
            }else{
                ssh.sftp("",'grep -o "ERROR" '+log_path+'.log.'+yr+'-'+mnth+'-* | wc -l', function(err, data) {
                    if(err){
                        reject(err)
                    }else{ 
                        resolve(data)
                    }
                })
            }
        })
    })
}

теперь вы можете переписать свою функцию cron, чтобы она стала асинхронной.

var cronFunction = async function(inputStr) { 
    if(appNames['applications'].length>0){ 
        for (i = 0; i < appNames["applications"].length; i++) {
            try{
                output_data + = await getDataFromServer(appNames["applications"][i].Name,appNames["applications"][i].hostname, appNames["applications"][i].username, appNames["applications"][i].password, appNames["applications"][i].log_path)
            }catch(err){
               logger.info("Error is in cronFunction = ", err);
            }
            ssh.close_second();
        }
    } 
}

async await позволяет вам писать асинхронный код в стиле синхронного кодирования. Однако асинхронное ожидание в настоящее время (узел 7.*) скрыто за флагом (--harmony-async-await). эта функция будет включена по умолчанию в следующем выпуске узла (8.0.0) в апреле 2017 года.

поэтому, чтобы запустить приложение, которое вы в настоящее время должны использовать

node --harmony-async-await yourapp.js

P.S.: Этот код в настоящее время не тестировался и, скорее всего, содержит ошибки ... но вы поняли идею.

person Holger Will    schedule 12.01.2017
comment
Спасибо...попробую.... :) Также я забыл упомянуть еще об одной ошибке, с которой я столкнулся....цикл for работает примерно 20 раз.....и как только счет достигает 20.. .. я получаю ошибку HandShanke ....... Любые предложения по этому поводу ??? - person Sshastry; 13.01.2017
comment
это также должно исчезнуть с async await, так как всегда будет только одно открытое соединение. - person Holger Will; 13.01.2017