npm 包 serial-port 与 meteor 的光纤错误
Fiber Error with npm package serial-port with meteor
我正在使用带有 meteor 的 SerialPort npm 包。我已经使用 wrapAsync 列出串行端口,但我不知道如何使用 serialPort.on 方法。
当我想在我的汽车中插入数据时出现错误 collection :
Meteor code must always run within a Fiber. Try wrapping callbacks
that you pass to non-Meteor libraries with Meteor.bindEnvironment.
代码:
Meteor.startup(function () {
SerialPort = Meteor.npmRequire('serialport');
// Wrap method SerialPort.list to call it Synchronously
listSerialPorts = function(callback) {
SerialPort.list(function (err, ports) {
callback(null, ports);
});
}
// Reset cars collection
});
Meteor.methods({
serialPortsRefresh: function () {
// TODO : problem when several arduinos ?
Config.remove({key:'serialPorts'});
// Call SerialPort.list
var asyncListSerialPorts = Meteor.wrapAsync(listSerialPorts);
var resultsListSerialPorts = asyncListSerialPorts();
// Insert results in database
var configSerialPorts = {key: "serialPorts", value: resultsListSerialPorts[0].comName };
Config.insert(configSerialPorts);
},
// Connect Serial port
serialPortConnect: function (port) {
// debugger;
// serialPort = new SerialPort(port.value, {baudrate: 9600});
serialPort = new SerialPort.SerialPort("/dev/ttyUSB0", {baudrate: 9600, parser: SerialPort.parsers.readline("\n")});
// connectSerialPort(port);
serialPort.on('open', function() {
console.log('Port ' + port.value + ' open');
});
serialPort.on('data', function(data) {
dispatchMessages(data);
//Watchdog.insert({key: "Receiving data", value: data })
});
sendToArduino = function(message) {
console.log(message);
serialPort.write(message);
};
dispatchMessages = function(data) {
console.log(data);
//Split data
var datas = data.split(" ");
if (datas[1] == "OK") {
console.log("Car " + datas[0] + " is here");
// Add car to database
Cars.insert({
cid: datas[0],
active: true
});
}
};
},
// Ping bridge
ping: function () {
sendToArduino("LED13\n");
}
});
问题是您传递给 serialPort.on
的回调在被调用时不会 运行 在与您的方法相同的纤程中。事实上,它们根本不会 运行 在光纤中,除非你适当地包裹它们。
Meteor.bindEnvironment
运行s 在纤程中传递的函数,但也在周围环境中复制,这是必要的,因为 Meteor 在当前纤程中存储各种变量,这可能需要运行 有问题的回调。
因此,如果您这样做,它应该会起作用:
serialPort.on('open', Meteor.bindEnvironment(function() {
// Wrapping this one is unnecessary at present as it doesn't
// do anything that needs to be run in a fiber, but you should
// probably wrap it anyway so that you can safely add more code
// if required.
console.log('Port ' + port.value + ' open');
}, function(e) {
// This is an error-handler - you don't have to pass one, but
// if you don't it can make debugging a nightmare.
throw e;
}));
serialPort.on('data', Meteor.bindEnvironment(function(data) {
dispatchMessages(data);
//Watchdog.insert({key: "Receiving data", value: data })
}, function(e) {
throw e;
}));
请注意,您还需要将回调包含在回调等中,这可能会变得非常冗长(并且将 var mBE = Meteor.bindEnvironment
之类的内容放在方法文件的顶部是个不错的主意)。
我正在使用带有 meteor 的 SerialPort npm 包。我已经使用 wrapAsync 列出串行端口,但我不知道如何使用 serialPort.on 方法。 当我想在我的汽车中插入数据时出现错误 collection :
Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
代码:
Meteor.startup(function () {
SerialPort = Meteor.npmRequire('serialport');
// Wrap method SerialPort.list to call it Synchronously
listSerialPorts = function(callback) {
SerialPort.list(function (err, ports) {
callback(null, ports);
});
}
// Reset cars collection
});
Meteor.methods({
serialPortsRefresh: function () {
// TODO : problem when several arduinos ?
Config.remove({key:'serialPorts'});
// Call SerialPort.list
var asyncListSerialPorts = Meteor.wrapAsync(listSerialPorts);
var resultsListSerialPorts = asyncListSerialPorts();
// Insert results in database
var configSerialPorts = {key: "serialPorts", value: resultsListSerialPorts[0].comName };
Config.insert(configSerialPorts);
},
// Connect Serial port
serialPortConnect: function (port) {
// debugger;
// serialPort = new SerialPort(port.value, {baudrate: 9600});
serialPort = new SerialPort.SerialPort("/dev/ttyUSB0", {baudrate: 9600, parser: SerialPort.parsers.readline("\n")});
// connectSerialPort(port);
serialPort.on('open', function() {
console.log('Port ' + port.value + ' open');
});
serialPort.on('data', function(data) {
dispatchMessages(data);
//Watchdog.insert({key: "Receiving data", value: data })
});
sendToArduino = function(message) {
console.log(message);
serialPort.write(message);
};
dispatchMessages = function(data) {
console.log(data);
//Split data
var datas = data.split(" ");
if (datas[1] == "OK") {
console.log("Car " + datas[0] + " is here");
// Add car to database
Cars.insert({
cid: datas[0],
active: true
});
}
};
},
// Ping bridge
ping: function () {
sendToArduino("LED13\n");
}
});
问题是您传递给 serialPort.on
的回调在被调用时不会 运行 在与您的方法相同的纤程中。事实上,它们根本不会 运行 在光纤中,除非你适当地包裹它们。
Meteor.bindEnvironment
运行s 在纤程中传递的函数,但也在周围环境中复制,这是必要的,因为 Meteor 在当前纤程中存储各种变量,这可能需要运行 有问题的回调。
因此,如果您这样做,它应该会起作用:
serialPort.on('open', Meteor.bindEnvironment(function() {
// Wrapping this one is unnecessary at present as it doesn't
// do anything that needs to be run in a fiber, but you should
// probably wrap it anyway so that you can safely add more code
// if required.
console.log('Port ' + port.value + ' open');
}, function(e) {
// This is an error-handler - you don't have to pass one, but
// if you don't it can make debugging a nightmare.
throw e;
}));
serialPort.on('data', Meteor.bindEnvironment(function(data) {
dispatchMessages(data);
//Watchdog.insert({key: "Receiving data", value: data })
}, function(e) {
throw e;
}));
请注意,您还需要将回调包含在回调等中,这可能会变得非常冗长(并且将 var mBE = Meteor.bindEnvironment
之类的内容放在方法文件的顶部是个不错的主意)。