Xmlrpclib

From MoDe

Table of contents

xmlrpclib: Remote Procedure Calls Made Easy in Python

My team for Boggle decided that we wanted to make a multiplayer version of the game. In order to implement the game server, we used xmlrpclib to abstract away much of the message passing that was going on so we could focus on making the game fun and not dealing with parsing XML manually.

This is a short guide to get you started with xmlrpclib if you think it would be helpful for one of your future projects. -Corey (mailto:coreymcc@mit.edu)

Setting up the Environment

You will need to install at least one package from the Familiar 0.8.3 feed: python-xmlrpc. It has several prerequisites, including python-shell, python-netclient, and python-xml.

You will also want to download xmlrpcserver.py (http://web.mit.edu/coreymcc/www/boggle/xmlrpcserver.py), a free companion to xmlrpclib that makes the task of writing your remote server easier.

 Warning: If you are also using PyGTK, your code must import xmlrpclib before you import gtk.

Writing the Remote Method

The remote method on the server is easy to write. As long as your method returns nothing, a number, string, list, tuple, dictionary, etc. then xmlrpclib will handle all of the message passing for you behind the scenes.

For example:

 class MyServer:
   def square(self, x):
     return x*x

Writing the Request Handler

The request handler processes incoming requests on the server and dispatches the remote call to the remote method with the appropriate parameters.

 import sys
 sys.path.append(".") # Assumes xmlrpcserver.py is in the same directory as your program.
 import xmlrpclib, xmlrpcserver, traceback
 myServer = None
 class MyRequestHandler(xmlrpcserver.RequestHandler):
   """Host Boggle games"""
   #Override method:
   def call(self, method, params):
     print "Dispatching: ", method, params
       try:
         server_method = getattr(self, method)
         return server_method(params)
       except:
         print "Propagating exception to user code:"                                                                       
         traceback.print_exc(file=sys.stdout)
         raise                                                   
   def cube(self, params):
       global myServer
       return myServer.cube(params[0])
 if __name__ == '__main__':
   myServer = MyServer()
     server = SocketServer.TCPServer((, <port>), BoggleRequestHandler)
     server.serve_forever()

In my experience working with xmlrpclib/xmlrpcserver, I found that I was always required to return some value, even if it was ignored, and it could not be None. I suspect that it may not be too difficult to modify parts of it to allow returning None, however.

Writing the Client Call

Once the server is up and running, now, in the client, all we have to do is point it to the server and make the call:

 import xmlrpclib
 server = xmlrpclib.Server("http://<host>:<port>")
 print server.square(3)
This could should print the number 9 to the console.