[Rprotobuf-yada] rpc over http

Romain François francoisromain at free.fr
Wed Dec 9 11:57:01 CET 2009


Hello,

I'm moving on with protobuf over http.

===== java server =====

I have commited a __very__ basic java server (I think it needs java 6) 
to the java directory of the project which receives protobuf http 
requests, invokes the method, and return the result as an http response. 
(At the moment, only the tutorial.EchoService.Echo rpc method is 
implemented, which basically receives a tutorial.Person message and send 
it back as is).

To compile the server, just go to the java directpry and type "ant", you 
should see something like this:

[romain at santorini java]$ ant
Buildfile: build.xml

clean:
    [delete] Deleting directory /home/romain/svn/rprotobuf/java/build
    [delete] Deleting directory /home/romain/svn/rprotobuf/java/javadoc
    [delete] Deleting directory /home/romain/svn/rprotobuf/java/jar

init:
     [mkdir] Created dir: /home/romain/svn/rprotobuf/java/build
     [mkdir] Created dir: /home/romain/svn/rprotobuf/java/javadoc
     [mkdir] Created dir: /home/romain/svn/rprotobuf/java/jar

build:
     [javac] Compiling 4 source files to 
/home/romain/svn/rprotobuf/java/build
       [jar] Building jar: 
/home/romain/svn/rprotobuf/java/jar/RProtoBuf-java-http.jar

all:

BUILD SUCCESSFUL
Total time: 1 second

To run the server :

$ java -cp jar/RProtoBuf-java-http.jar 
org.rproject.rprotobuf.ProtobufHttpServer


===== R client =====

now it gets interesting with the R client. I have also commited some 
code to invoke a rpc method over http.

To call a rpc method over http, you need 3 things:
- a method descriptor.
- an input message which must be of the message type that the method expects
- a "RpcHTTP" object which represents the protocol used (contains host 
name and port number)

It goes like this :

require( RProtoBuf )
p <- new( tutorial.Person, name = "foo", id = 2, email = "bla at bla.com" )
http <- new( "RpcHTTP", host = "127.0.0.1", port = 4444L)
result <- invoke( tutorial.EchoService.Echo, p, http )
writeLines( result$toString() )

On the client side (the R console), you should see this (the debugging 
information will eventually go) :

 > source("send.R" )
sending http request
headers : sent 83 bytes
input message : sent 20 bytes
reading 59 bytes
complete line: {HTTP/1.1 200 OK}
complete line: {Content-length: 20}
header 'content-length' => '20'
end of request - moving to body
name: "foo"
id: 2
email: "bla at bla.com"

and this on the server side :

ProtobufHandler >> handle
http method : POST
Content-length=[20]
Connection=[close]
rpc method : {tutorial.EchoService.Echo}
  read 20 bytes
finished reading body
sending result : 20 bytes



===== the protocol =====

This is just (ab)using the http protocol.

The client sends a request that looks like this :

-----------------------------------------------------
POST /{service full name}/{method name} HTTP/1.0
Connection: close
Content-Length: {length of the serialized message}

{raw bytes of the serialized message}
-----------------------------------------------------

The server replies with something that looks like this :

-----------------------------------------------------
HTTP/1.1 200 OK
Content-length: {length of the serialized response}

{raw bytes of the serialized response}
-----------------------------------------------------

or like this if the method is unknown :

-----------------------------------------------------
HTTP/1.1 501
-----------------------------------------------------




===== what's next =====

I need to make the java server a bit nicer and maybe release it 
separately. I chose http as a first attempt because it will be "easy" to 
implement with other languages, and because that is what kenton 
recommended.

When R is ready to serve, I'll make a server so that two instances of R 
can exchange protobuf messages

I really need to think about another protocol. http "works" but I think 
it is too verbose. In the example, it needs to send 103 bytes (83+20) to 
send a message that takes only 20 bytes. The response also takes too 
much space. No big deal but we can do better than that.

I need some nicer examples of methods. Echo is a bit too dummy.

The code for the R client is all in rpc_over_http.cpp. This is very 
inspired from the Rhttp.c from the R sources, it probably should get c++'ed.

I need to document it.


Romain


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/Gq7i : ohloh
|- http://tr.im/FtUu : new package : highlight
`- http://tr.im/EAD5 : LondonR slides



More information about the Rprotobuf-yada mailing list