1

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

2 回答 2

0

两个错误:

  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'                                                             
});
于 2015-01-27T05:50:52.263 回答
0

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

如何从 Meteor 自己的回调中调用异步方法?

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));
    }
});
于 2015-05-17T13:55:38.167 回答