I received a question the other day about using our
XML-RPC library, and thought I’d put the response here.
It’s still a simple example, but it illustrates one or two
things. You must be running PLT Scheme 352.5 or greater
for this to work, as we’re using some nifty new features
that make things more stable.
I’m going to implement a “live hash-table”. By this, I
mean I’m going to have a PLT Scheme hash-table that I can
access from anywhere via XML-RPC. I created a “testing”
directory in in the “servlets” directory of my server.
Inside of that “testing” directory, I created a servlet
called “live-hash.ss”. It looks like this:
(module live-hash mzscheme
(require
;; For the 'xmlrpc-server' and 'add-handler' functions
(planet "xmlrpc-module-servlet.ss"
("schematics" "xmlrpc.plt" 1 3))
;; For 'raise-exn:xmlrpc'
(planet "base.ss"
("schematics" "xmlrpc.plt" 1 3))
)
(provide interface-version manager timeout start)
;; I'm using 'equal here so that strings can be
;; used as hashtable keys.
(define table (make-hash-table 'equal))
;; CONTRACT
;; insert : (U string number) any -> bool
;; PURPOSE
;; The 'insert' method will insert a value into the
;; hashtable, and return #t. We return a boolean in all
;; casees because XML-RPC has no natural coercion for the
;; #<void> value.
(define (insert key value)
(if (or (string? key)
(number? key))
(begin (hash-table-put! table key value) #t)
#f))
;; CONTRACT
;; get : (U string number) -> any
;; PURPOSE
;; The 'get' method returns a value from the hashtable, or
;; raises an XML-RPC fault.
(define (get key)
(hash-table-get
table key
(lambda ()
(raise-exn:xmlrpc
(format "No value in hash for key '~a'" key))
)))
;; Make 'insert' and 'get' available to the
;; outside world.
(add-handler 'insert insert)
(add-handler 'get get)
)
If you can execute this in the “module” language of
DrScheme and not get any errors, there’s a good chance
that it will run under the webserver. At least, that’s a
first step.
On the client side, I have some code that declares that
the PLT webserver running on my local machine (with the
“live-hash.ss” servlet) is an XML-RPC endpoint. I then map
two local functions, “ins” and “get” to the remote methods
provided by the server. Lastly, I do a quick test: I
insert some data, and then request it back.
The client-side looks like:
(module live-hash-client mzscheme
(require (planet "xmlrpc.ss"
("schematics" "xmlrpc.plt" 1 3)))
;; Declare where the endpoint for this XML-RPC call is
(define local (xmlrpc-server
"localhost"
8080
"servlets/testing/live-hash.ss"))
;; Define the mappings from local method calls to remove
;; method calls. In this case, the local name "ins" is bound
;; to the method "insert" running on the server.
(define ins (local 'insert))
(define get (local 'get))
;; Try inserting some data
(for-each (lambda (key val)
(ins key val))
'(1 2 3 4 5)
'(a b c d e))
;; Now, try retrieving it
(for-each (lambda (key)
(printf "K: ~a V: ~a~n" key (get key)))
'(1 2 3 4 5))
)
Again, I’m working under the “module” language here.
If all goes well, you can run the client-side, and see the
data go round-trip to the server. Well, you can’t exactly
“see” it, but you can guess that it goes round-trip to the
server.
Welcome to DrScheme, version 352.5-svn28aug2006.
Language: (module ...).
K: 1 V: a
K: 2 V: b
K: 3 V: c
K: 4 V: d
K: 5 V: e
That’s perhaps not a lot to be getting on with; there’s
more documentation in the “doc.txt” file included in the
distribution. And it’s not quite as cool as Tony’s explorations with Erlang, but… well, this library has been around for a while,
and occasionally, someone finds a use for it.
(Pretty-printing of code to HTML made possible by Paste Scheme at scheme.dk. Woot.)