我正在编写一个在服务器上执行多个shell命令的Meteor应用程序。我想要从服务器到客户端的实时输出,但我在查找实时部分时遇到了麻烦。我不想等待命令完成 - 因为它可能需要很长时间。
现在我已经创建了一个Logs Mongo集合来存储输出。但是我得到这样的错误:"错误:Meteor代码必须始终在Fiber中运行。尝试使用Meteor.bindEnvironment包装传递给非Meteor库的回调。"
听起来我Meteor要我等到所有输出都写完了。我不想包装Async,因为我希望在客户端打印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 :(得分:0)
Meteor.bindEnvironment()应解决您的问题:
command.stdout.on('data',
Meteor.bindEnvironment(
function (data) {
Logs.update({ branch: branch['name'] }, { branch: branch['name'], text: ''+data});
}
)
);
如果要在服务器端的回调中执行Meteor.update(),则需要在回调函数上使用wrapAsync或Meteor.bindEnvironment()。这是我在需要使用第三方库(如Stripe)时使用的,然后需要根据服务器端的回调更新一些数据。