rpc/jsonrpc example, please?

458 views
Skip to first unread message

Rodrigo Moraes

unread,
Oct 26, 2011, 9:32:23 AM10/26/11
to google-appengine-go
Hey,

I'm very confused reading the rpc & rpc/jsonrpc packages and docs.
Particularly how to serve a jsonrpc service in an App Engine setup. We
won't listen ports or call http.Serve() directly, so how it is done?

If you want to gain some karma (heh), I asked this here too:
http://stackoverflow.com/questions/7902954/using-rpc-jsonrpc-in-app-engine

thanks,
-- rodrigo

Brad Fitzpatrick

unread,
Oct 26, 2011, 11:45:43 AM10/26/11
to Rodrigo Moraes, google-appengine-go
Basically, you can't.  That's only the first problem you'll hit.  The second major problem you'll find is that you can't get at the *http.Request to get an appengine.Context to do anything useful with App Engine in your RPC handler.

You should file a general Go bug... "package rpc is not compatible with App Engine" or something.

Rodrigo Moraes

unread,
Oct 26, 2011, 11:55:51 AM10/26/11
to google-appengine-go
On Oct 26, 1:45 pm, Brad Fitzpatrick wrote:
> Basically, you can't.  That's only the first problem you'll hit.  

Oh. Man, this was puzzling me so much. I thought it was possible in
some way and I'd be stupid to not use the standard package. I'll
create my own.

> The second major problem you'll find is that you can't get at the *http.Request
> to get an appengine.Context to do anything useful with App Engine in your
> RPC handler.

I figured this already, but I would make the request available in some
way -- once I discovered how to actually serve any RPC.

> You should file a general Go bug... "package rpc is not compatible with App
> Engine" or something.

I'll do it once I explore this a bit more. Thanks, Brad.

-- rodrigo

Ugorji Nwoke

unread,
Oct 26, 2011, 3:05:10 PM10/26/11
to google-ap...@googlegroups.com
This was as far as I got when playing with it. With this, I'm not listening on ports or calling http.Serve. It almost works (except that http CONNECT method is not supported by app engine, as expected).

//on server side:
myobj := new(RPCHandle) //or whatever your type is
srvr := rpc.NewServer()
err := srvr.Register(myobj)
f1 := func(w http.ResponseWriter, req *http.Request) {
  srvr.ServeHTTP(w, req)
}
http.HandleFunc("/rpc", f1)

//on client side:
client, err := rpc.DialHTTPPath("tcp", "localhost:8080", "/rpc")
client.Call(...)

//On running, I get:
ERROR    ... dev_appserver.py:4134] code 501, message Unsupported method ('CONNECT')
INFO     ... dev_appserver.py:4143] "CONNECT /rpctestrunner HTTP/1.0" 501 -

AppEngine doesn't support CONNECT method, as I would expect (since CONNECT may want to hijack the socket connection and use it as it wants). I wonder if the rpc package can be made to work with just GET/POST. 


Rodrigo Moraes

unread,
Oct 26, 2011, 8:11:52 PM10/26/11
to google-appengine-go
On Oct 26, 5:05 pm, Ugorji Nwoke wrote:
> AppEngine doesn't support CONNECT method, as I would expect (since CONNECT
> may want to hijack the socket connection and use it as it wants). I wonder
> if the rpc package can be made to work with just GET/POST.

After a better look (and knowing I wasn't missing something), I think
it goes well beyond that. The server from the rpc package is designed
to keep a persistent connection with a client, not to serve ephemeral
individual requests.

I honestly have no idea how easy would it be to extend it to support
the latter, so I'm planning to implement a very simple jsonrpc server
following the vasic API from the rpc package, minus the persistent
connection model, and making request available so that we can plug
stuff into it (like using App Engine services).

-- rodrigo

Brad Fitzpatrick

unread,
Oct 26, 2011, 8:26:52 PM10/26/11
to Rodrigo Moraes, google-appengine-go
On Wed, Oct 26, 2011 at 5:11 PM, Rodrigo Moraes <rodrigo...@gmail.com> wrote:
On Oct 26, 5:05 pm, Ugorji Nwoke wrote:
> AppEngine doesn't support CONNECT method, as I would expect (since CONNECT
> may want to hijack the socket connection and use it as it wants). I wonder
> if the rpc package can be made to work with just GET/POST.

After a better look (and knowing I wasn't missing something), I think
it goes well beyond that. The server from the rpc package is designed
to keep a persistent connection with a client, not to serve ephemeral
individual requests.

It wouldn't be as efficient, but I think it could be made to work.  Every request would be like the first one in a TCP connection, with all the type metadata.  You wouldn't get the gob efficiencies of reusing types later.

tav

unread,
Oct 26, 2011, 9:08:58 PM10/26/11
to Rodrigo Moraes, google-appengine-go
For what it's worth, I was able to get rpc working over app engine
with some minor changes to the rpc package:

* https://github.com/tav/togethr/commit/1b277f689eee76b6a6b9dc4cbb013ad6d1c70246

It supports appengine.Context and allows for rpc calls to be proxied
over standard requests with a fairly simple wrapper, e.g.

* https://github.com/tav/togethr/blob/c8921d21121ca91ea92b8d917d889ff7f650ba16/gaestore/gaestore/main.go

--
Hope that helps, tav

plex:espians/tav | t...@espians.com | +44 (0) 7809 569 369
http://tav.espians.com | http://twitter.com/tav | skype:tavespian

Rodrigo Moraes

unread,
Oct 27, 2011, 5:11:18 AM10/27/11
to google-appengine-go
On Oct 26, 11:08 pm, tav wrote:
> For what it's worth, I was able to get rpc working over app engine
> with some minor changes to the rpc package:

Hey tav,

I would not call those "minor" but wow, thanks for sharing this. It
will help a lot. :)

I created an issue in case you want to follow:
http://code.google.com/p/go/issues/detail?id=2404

-- rodrigo

Ugorji Nwoke

unread,
Oct 27, 2011, 11:50:30 AM10/27/11
to google-ap...@googlegroups.com


On Wednesday, October 26, 2011 8:11:52 PM UTC-4, Rodrigo Moraes wrote:
On Oct 26, 5:05 pm, Ugorji Nwoke wrote:
> AppEngine doesn't support CONNECT method, as I would expect (since CONNECT
> may want to hijack the socket connection and use it as it wants). I wonder
> if the rpc package can be made to work with just GET/POST.

After a better look (and knowing I wasn't missing something), I think
it goes well beyond that. The server from the rpc package is designed
to keep a persistent connection with a client, not to serve ephemeral
individual requests.

That's what I was implying. http CONNECT is usually used by servers that want to bypass the http protocol and *hijack* a socket connection to do as they want (keep it alive till they are done, use a different protocol, etc). By making the rpc package work with just GET/POST, the explicit hijack/persistent model goes away in that situation.

-- rodrigo
Reply all
Reply to author
Forward
0 new messages