imagemagick in meteorjs (with the help of meteor-router and fibers)

一世执手 提交于 2019-12-07 14:35:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!