2016-01-06 3 views
1

Я пишу приложение Meteor, которое выполняет несколько команд оболочки на сервере. Я хочу получать в реальном времени от сервера к клиенту, но у меня возникли проблемы с поиском части в реальном времени. Я не хочу ждать завершения команды - так как это может занять много времени.MeteorJS обратная связь в реальном времени с сервера

На данный момент я создал коллекцию Logs Mongo для хранения выходных данных. Но я получаю такие ошибки: «Ошибка: код Метеор должен всегда работать внутри Fiber. Попробуйте обертывать обратные вызовы, которые вы передаете библиотекам не-Метеор с Meteor.bindEnvironment ".

Похоже, что я Метеор хочет, чтобы я подождал, пока все выходные данные будут записаны. Я не хочу wrapAsync, потому что я хочу, чтобы выход async был напечатан на стороне клиента, поскольку он идет по строкам. Spawn возвращает поток на сервере, так что сторона покрыта, у меня просто возникают проблемы с потоковой передачей клиенту. Вот пример:

Logs = new Mongo.Collection("logs"); 

if (Meteor.isClient) { 

    Template.body.helpers({ 
    log: function(branchName) { 
     return Logs.find({}); 
    } 
    }); 

    Template.branch.events({ 
    'click button#start': function(event, template) { 
     Meteor.call('startStack', template.data, function(error, result) { 
     if(error){ 
      console.log(error); 
     } else { 
      console.log('response: ', result); 
     } 
     }); 
    } 
    }); 

} 

if (Meteor.isServer) { 
    spawn = Npm.require('child_process').spawn; 

    Meteor.methods({ 

    startStack: function(branch) { 
     command = spawn('sh', ['-c', "ls && sleep 2 && ls -l && sleep 3 && ls -la"]); 

     Logs.update({ branch: branch['name'] }, { branch: branch['name'], text:''}, { upsert : true }); 

     command.stdout.on('data', function (data) { 
     // TODO: concat to existing text 
     Logs.update({ branch: branch['name'] }, { branch: branch['name'], text: ''+data}); 
     }); 
    } 
    }); 

} 

ответ

0

Meteor.bindEnvironment() должен решить проблему:

command.stdout.on('data', 
    Meteor.bindEnvironment(
     function (data) { 
      Logs.update({ branch: branch['name'] }, { branch: branch['name'], text: ''+data}); 
     } 
    ) 
); 

Если вы собираетесь сделать Meteor.update() в функции обратного вызова на стороне сервера необходимо будет использовать wrapAync или Meteor.bindEnvironment() для функции обратного вызова. Это то, что я использую, когда мне нужно использовать стороннюю библиотеку (например, Stripe), а затем необходимо обновить некоторые данные, основанные на обратном вызове на стороне сервера.

+1

Спасибо. Похоже на то, что мне нужно. Понял, что это было что-то простое. Все еще обертываю голову вокруг модели метеор. – Jono

Смежные вопросы