uber-archive / multitransport-jsonrpc

JSON-RPC Client (Node.js & Browser) and Server (Node.js) aim at "natural looking" server and client code.
116 stars 22 forks source link

Unable to log REPL response #62

Closed timmysze closed 9 years ago

timmysze commented 9 years ago

I'm trying to console.log the response from executing a remote method from the REPL. I may be overlooking something obvious, but it seems like the callback isn't executed on the client.

For example, if I do jsonrpc> rpc.foo('arg1', function () {console.log('bar')});, the anonymous function doesn't seem to be called and I don't see bar, even though I can confirm that foo was executed on the server and the server called the cb.

Any help would be much appreciated. Thanks.

dfellis commented 9 years ago

What's the argument length of the method on the server? They need to match exactly with how you call the method on the client for it to call your callback appropriately.

timmysze commented 9 years ago

Thanks for responding so quickly! The method on the server takes one argument plus the callback and I can confirm that 'arg1' is received. I only seem to have this issue in the REPL. My actual node apps work that are doing the same thing as I am manually in the REPL are working as expected.

dfellis commented 9 years ago

So I'm going to need a little more detail on this. I just wrote a test server:

var jsonrpc = require('multitransport-jsonrpc');

var HttpServer = jsonrpc.transports.server.http;
var Server = jsonrpc.server;

new Server(new HttpServer(8000), {
    foo: function(val, callback) {
        callback(undefined, val + '!');
    }
});

And here are my REPL results:

damocles@moya:~/uber/test$ ./node_modules/.bin/jsonrpc-repl -p 8000
Connected to localhost:8000 over HTTP
The server reported the following methods:
foo, rpc.methodList
Access them with `rpc.foo(arg1, arg2, callbackFunction)`
jsonrpc> rpc['rpc.methodList'](console.log);
undefined
jsonrpc> undefined [ 'foo', 'rpc.methodList' ]

undefined
jsonrpc>
undefined
jsonrpc> rpc.foo('bar', console.log)
undefined
jsonrpc> undefined 'bar!'

undefined
jsonrpc>
(^C again to quit)
jsonrpc>
damocles@moya:~/uber/test$

Nothing appears out of the ordinary to me?

timmysze commented 9 years ago

@dfellis Thanks, that actually basically helped solve my issue. Here's what I get when I try it:

var jsonrpc = require('multitransport-jsonrpc');

var TCPServer = jsonrpc.transports.server.tcp;
var Server = jsonrpc.server;

new Server(new TCPServer(8000), {
    foo: function(val, cb) {
        cb(undefined, val + '!');
    }
});

And REPL results:

➜  compgun-login git:(dev) ✗ jsonrpc-repl -s localhost -p 8000 -t
Connected to localhost:8000 over TCP
The server reported the following methods:
foo, rpc.methodList
Access them with `rpc.foo(arg1, arg2, callbackFunction)`
jsonrpc> rpc.foo('bar', console.log)
undefined
jsonrpc> undefined 'bar!'

undefined
jsonrpc> rpc.foo('bar', function (err, resp) { console.log(resp); })
undefined

So first call works. I still can't see what I was doing wrong in the second call. In any case, thanks again.

dfellis commented 9 years ago

Huh. I don't see what's wrong with your second invocation either, unless the repl does something weird with console.log that doesn't affect calling the log method with the wrong this.

(The first invocation passes the console.log method without binding, so when log is called, it'll be in the context of the repl object, not the console object.)

Can you try something like this:

var log = console.log;
rpc.foo('bar', function(err, res) { log(res); });
timmysze commented 9 years ago

I get:

jsonrpc-repl -s localhost -p 8000 -t
Connected to localhost:8000 over TCP
The server reported the following methods:
foo, rpc.methodList
Access them with `rpc.foo(arg1, arg2, callbackFunction)`
jsonrpc> rpc.foo('bar', console.log)
undefined
jsonrpc> undefined 'bar!'

undefined
jsonrpc> var log = console.log;
undefined
jsonrpc> rpc.foo('bar', function(err, res) { log(res); });
undefined

Good to know that it wasn't just me missing something very obvious...

dfellis commented 9 years ago

Very strange. I'd have to defer to someone more deeply versed in the Node repl's internals (like @Raynos ) but there's clearly something special that it does when passing console.log as the callback function that doesn't happen if you pass a callback that then calls console.log.

kalinkrustev commented 9 years ago

Seems instanceof Function is not recognizing functions defined in the repl. You need to run the repl with the useGlobal=true:

var r = repl.start({prompt:'jsonrpc> ', useGlobal:true});
dfellis commented 9 years ago

Interesting. I'm going to try that and then make a diff to fix that. Thanks!

dfellis commented 9 years ago

Yep, that works!

damocles@moya:~/uber/multitransport-jsonrpc(master)$ ./bin/jsonrpc-repl -p 8000 -t
Connected to localhost:8000 over TCP
The server reported the following methods:
foo, rpc.methodList
Access them with `rpc.foo(arg1, arg2, callbackFunction)`
jsonrpc> rpc.foo('bar', console.log)
undefined
jsonrpc> undefined 'bar!'
jsonrpc> rpc.foo('baz', function (err, res) { console.log(res); });
undefined
jsonrpc> baz!

undefined
jsonrpc>