【问题标题】:Using node-rio from Meteor Server Side Route使用 Meteor Server Side Route 中的 node-rio
【发布时间】:2015-01-27 04:00:17
【问题描述】:

我正在尝试使用 Meteor 通过服务器端路由访问 Rserve 服务器以调用 R 代码。允许访问 Rserve 的 Node.js 模块是 node-rio 我使用了 meteorhacks:npm Meteor 包中的 Async.wrap 函数来包装“评估”方法。当我尝试在浏览器中访问路由路径“/rio”时,控制台日志中写入了“1”,这对于 R 中命令“1”的评估是正确的,但 Chrome 挂起并显示消息“正在等待对于本地主机”。它不会进入下一行,并且永远不会显示“结果:1”。消息“net::ERR_EMPTY_RESPONSE 最终会出现在 Chrome 中。

Router.route('/rio', function() {
    var rio = Meteor.npmRequire('rio');
    var evalSync = Async.wrap(rio, 'evaluate');
    var result = evalSync('1');
    console.log("Result: " + result);

    // JSON
    this.response.writeHead(200, {'Content-Type': 'application/json'});
    this.response.end(result);
}, {
    where: 'server'
});

“evaluate”有一个回调函数参数,但它被包裹在一个选项参数中并被访问:

rio.evaluate(R_COMMAND, {callback: CALLBACK_FUNCTION})

【问题讨论】:

    标签: node.js meteor rserve


    【解决方案1】:

    两个错误:

    1. 正如您已经指出的那样,rio 期望回调作为参数中回调字段的值,而不是直接在参数本身中。
    2. 您的结果(“1”)实际上不是有效的 JSON。

    这行得通:

    Router.route('/rio', function() {                                               
        var rio = Meteor.npmRequire('rio');                                         
        var evalSync = Async.wrap(function(exp, callback) {                         
            rio.evaluate(exp, {callback: callback});                                
        });                                                                         
        var result = evalSync('1');                                                 
        console.log("Result: " + result);                                           
    
        // JSON                                                                     
        this.response.writeHead(200, {'Content-Type': 'application/json'});         
        this.response.end(JSON.stringify({result: result}));                        
    }, {                                                                            
        where: 'server'                                                             
    });
    

    【讨论】:

    • 对于以下基本 R 表达式,'packageVersion("base")' 我收到以下错误:[object Object] 处的包/meteorhacks:async/async.js:71:1 处出错。 router.route.where (app/both/router/routes.js:136:18) 在 runWithEnvironment (packages/meteor/dynamics_nodejs. js:108:1) at packages/meteor/dynamics_nodejs.js:121:1 ...我使用 Future 添加了一个答案,其行为符合我的预期。
    【解决方案2】:

    这个答案将产生'packageVersion("base")'的预期结果,它使用节点模块rserve-client而不是rio来连接到Rserve。该路由还处理参数“pkg”。这是为我指明正确方向的 StackOverflow 问题:

    How to call async method from Meteor own callbacks?

    Router.route('rserve', {
        path: '/rserve/:pkg',
        where: 'server',
        action:  function() {
            var r = Meteor.npmRequire("rserve-client");
            var Future = Meteor.npmRequire("fibers/future");
            var fut = new Future();
    
            var cmd = 'packageVersion("' + this.params.pkg + '")';
    
            var callR = function (input) {
                r.connect('127.0.0.1', 6311, function (err, client) {
                    client.evaluate(input, function (err, ans) {
                        console.log("Result: " + ans);
                        client.end();
    
                        fut.return(ans);
                    });
                });
    
                return fut.wait();
            };
    
            var result = callR(cmd);
    
            this.response.writeHead(200, {'Content-Type': 'application/json'});
            this.response.end(JSON.stringify(result));
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-21
      • 2013-01-27
      相关资源
      最近更新 更多