69
def _ _init_ _(self, host=None, port=8182):
if host is None:
host = gethostname( )
self.host = "%s:%s" % (host, port)
self.transport = Transport( )
def remote(self, method, params=( )):
""" remote invokes the server with the method name
and an optional set
of parameters. The return value is always a tuple.
"""
response = self.transport.request(self.host, '/RPC2',
dumps(params,
method))
return response
if _ _name_ _ == '_ _main_ _':
connection = xmlrpc_connection( )
(answer,) = connection.remote("add", (40, 2))
print "The answer is:", answer
13.4.3 Discussion
This recipe demonstrates remote method calls between two machines (or two processes, even on
the same machine) using the XML-RPC protocol. A complete example of working client/server
code is provided. XML-RPC is one of the easiest ways to handle distributed processing tasks.
There's no messing around with the low-level socket details, nor is it necessary to write an
interface definition. The protocol is platform- and language-neutral. The XML-RPC specification
can be found at http://www.xml-rpc.com
and is well worth studying.
With Medusa (http://www.nightmare.com
), you implement an XML-RPC server by subclassing
the
xmlrpc_handler
class and passing an instance of your class to the
install_handler
method of an instance of
http_server
. HTTP is the transport-level
protocol, and
http_server
handles all transport-level issues on your behalf. You need to
provide only the handler part by customizing
xmlrpc_handler
through subclassing and
method overriding. Specifically, you must override the
call
method, which the Medusa
framework calls on your instance with the name of the XML-RPC method being called, along
with its parameters, as arguments. This is exactly what we do in this recipe, in which we expose a
single XML-RPC method named
add
which accepts two numeric parameters and returns their
sum as the method's result.
The sample XML-RPC client uses
xmlrpclib
in a more sophisticated way than Recipe 13.2
by using the
Transport
class explicitly. This lets you see what happens under the covers of an
XML-RPC method call a bit more transparently and also lets you control things in a finer-grained
way, although we don't use that fine-grained-control potential in this recipe (and you will need it
only rarely in XML-RPC clients that you actually deploy, anyway).
xmlrpclib
can also be used on its own, without separately downloading and installing Medusa,
and comes with similar client and server program examples. However, the asynchronous operation
of Medusa can significantly enhance performance, particularly scalability. Medusa (and
asyncore
and
asynchat
) are applicable to client- and server-side programming, but this
recipe does not use the asynchronous approach in its example client, only in its example server. Of
course, the benefits of the asynchronous approach come when a program does several network