meteorjs中的imagemagick(在流星路由器和光纤的帮助下)

时间:2012-12-13 10:28:35

标签: imagemagick meteor node-fibers

我无法在meteorjs中使用imagemagick。我正在研究一个小的svg-> png转换器,它包含一个rest api来提供转换后的图像。我用meteor-router实现了其余的api。 imagemagick转换有效。但是,我无法将转换结果写入http响应。我试图通过使用光纤去除异步性来解决这个问题。但这仍然行不通。基本上,在yield执行后会忽略所有request.write调用。这是我的代码:

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();

  }
});

我对meteorjs很新。因此,我可能使用光纤完全错误。或者我根本不应该使用光纤。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

感谢meteor-router的作者,我能够解决问题。我以错误的方式使用光纤。如https://github.com/laverdet/node-fibers#futures所述,不建议在代码和原始API之间使用光纤而不是抽象。

幸运的是,光纤提供了一个名为future的抽象,可以用于我的用例!这是工作代码:

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();
  });
});

答案 1 :(得分:0)

我做了一些调查。这个问题与imagemagick正交。例如:以下代码片段在meteor-router中也不起作用:

示例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); 
    }                                                                           
  }); 

示例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();   
    }                                                                           
  }); 

我认为这是流星路由器的一般问题。因为这两个例子都适用于纯nodejs。