Использование node-rio из бокового маршрута Meteor Server

Я пытаюсь получить доступ к серверу Rserve с помощью Meteor через маршрут на стороне сервера для вызова R-кода. Модуль Node.js, обеспечивающий доступ к Rserve, называется node-rio. Я использовал Async.wrap. в пакете meteorhacks:npm Meteor для переноса метода "evaluate". Когда я пытаюсь получить доступ к пути маршрута «/rio» в браузере, в журнал консоли записывается «1», что правильно для оценки команды «1» в R, но 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})

person cannin    schedule 27.01.2015    source источник


Ответы (2)


Две ошибки:

  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'                                                             
});
person Christian Fritz    schedule 27.01.2015
comment
Для следующего базового выражения R «packageVersion (base)» я получаю следующую ошибку: Ошибка в packages/meteorhacks: async/async.js: 71: 1 в [object Object].Router.route.where (app/both/ router/routes.js:136:18) вboundNext (packages/iron:middleware-stack/lib/middleware_stack.js:251:1) в runWithEnvironment (packages/meteor/dynamics_nodejs.js:108:1) в packages/meteor /dynamics_nodejs.js:121:1 ... Я добавил ответ, используя Future, который ведет себя так, как я ожидал. - person cannin; 17.05.2015

Этот ответ даст ожидаемый результат для '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));
    }
});
person cannin    schedule 17.05.2015