问题
I am unable to use imagemagick in meteorjs. I am working on a small svg->png converter which contains a rest api to provide the converted images. I implemented the rest api with meteor-router. The imagemagick convertion works. But, I am not able to write the result of the convertion into the http response. I tried to fix this by getting rid of the asynchronisity by using fiber. But this still doesn't work. Basically, all request.write calls are ignored after the yield execution. Here is my code:
Meteor.Router.add({
'/image/:hash' : function(hash) {
var svg = Images.findOne({'hash' : hash}).svg;
var request = this.request;
var response = this.response;
Fiber(function() {
var fiber = Fiber.current;
response.writeHead(200, {'Content-Type':'image/png'});
var convert = imagemagick.convert(['svg:-', 'png:-']);
convert.on('data', function(data) {
response.write("doesn't work");
//response.write(data);
});
convert.on('end', function() {
response.write("doesn't work");
//response.end();
fiber.run({});
});
convert.stdin.write(svg);
convert.stdin.end();
response.write("works");
Fiber.yield();
response.write("doesn't work");
}).run();
}
});
I am pretty new to meteorjs. Therefore, I might use Fiber completely wrong. Or I should not use fiber at all. Can someone help?
回答1:
Thanks to the author from meteor-router, I was able to fix the problem. I was using fiber the wrong way. As described at https://github.com/laverdet/node-fibers#futures, it's not recommended to use fiber without an abstraction between your code and the raw API.
Fortunately, fiber provides one abstraction called future which can be used for my use case! Here is the working code:
var require = __meteor_bootstrap__.require,
Future = require('fibers/future');
Meteor.startup(function() {
Meteor.Router.add('/image/:hash', function(hash) {
var response = this.response;
var fut = new Future();
response.writeHead(200, {'Content-Type':'text/plain'});
setTimeout(function(){
response.write("hello hello");
fut.ret();
}, 1);
fut.wait();
});
});
回答2:
I did some more investigation. The issue is orthogonal to imagemagick. E.g.: the following code snippets do not work too in meteor-router:
Example 1:
Meteor.startup(function() {
Meteor.Router.add({
'/image/:hash' : function(hash)
var request = this.request;
var response = this.response;
response.write("outside");
setTimeout(function(){
response.write("inside");
response.end();
}, 1);
}
});
Example 2:
Meteor.startup(function() {
Meteor.Router.add({
'/image/:hash' : function(hash)
var request = this.request;
var response = this.response;
response.write("outside");
Fiber(function() {
var fiber = Fiber.current;
setTimeout(function(){
response.write("inside");
response.end();
}, 1);
Fiber.yield();
}).run();
}
});
I think it's general issue of meteor-router. Because both examples do work with pure nodejs.
来源:https://stackoverflow.com/questions/13857866/imagemagick-in-meteorjs-with-the-help-of-meteor-router-and-fibers