[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