Multiplay Labs

tech hits and tips from Multiplay

Serving XML-RPC from Rails 2.x

with 3 comments

As part of our new Fileplay system, we’re implementing automated uploads of Match Demos at i35 direct to Fileplay. Our tournament admins at the events use ClanForge to manage the tournament, so we wanted to allow them to do it direct from there. Enter XML-RPC. ClanForge already speaks this, so it seemed the best way forward was to teach Rails to speak XML-RPC. Should be easy right?

Oh how wrong we were.

Googling around for a plugin to make this Just Workā„¢ yielded results for Rails pre-2.0 using ActionWebService, which is now unused and “ousted”. Luckily, the solution is simple using XMLRPC4R

As XML-RPC generally only has one endpoint, we simply create a new controller with an index action which will do all the request handling.

Within the action, we start out by instantiating a basic class that knows how to speak XML-RPC.

xmlrpc = XMLRPC::BasicServer.new

The docs for XMLRPC4R say that we should never need to instantiate this. The key word here is “should”, normally it’s subclassed by something that does the handling of the HTTP stuff. Not in this case as Rails is handling that.

Now we want to hand off the request to the XML-RPC library.

response = xmlrpc.process(request.body.read)

If an exception gets raised within our handler, it’ll get automagically converted into an XML-RPC fault structure. But we still want the error to appear in our log:

# Log the error if there is one
parser = XMLRPC::XMLParser::XMLStreamParser.new
ret = parser.parseMethodResponse(response)
logger.error("XMLRPC fault raised. Code: #{ret[1].faultCode}: Message: #{ret[1].faultString}") unless ret[0]

Finally, render the XML-RPC response.

render :text => response, :layout => false

XML-RPC Methods

So how do we define methods that the consumers of our service can… consume?

Easy.

# Handler definitions
xmlrpc.add_handler("file.get") do |fileid|
	file = Multiplay::Fileplay::File.find_by_fileid(fileid)
	raise XMLRPC::FaultException.new 404, "File Not Found" if file.nil?
	file
end

Sure it’ll capture any raised Exceptions, but if you want to pass something meaningful to consumers, raise an XMLRPC::FaultException with a faultCode and a faultString.

Remember, as this is a block, you can’t return from it. The value to return over XML-RPC will be the value yielded, in this case the file.

Written by Boffbowsh

October 24th, 2008 at 9:14 am

Posted in Code

Tagged with ,

3 Responses to 'Serving XML-RPC from Rails 2.x'

Subscribe to comments with RSS or TrackBack to 'Serving XML-RPC from Rails 2.x'.

  1. require ‘xmlrpc/server’ is sufficient, no need for xmlrpc4r.

    wolfhesse

    11 Feb 09 at 14:06

  2. wolfhesse — could you perhaps be a little more specific? Are you saying that xmlrpc4r is now built-in to Rails? No need to install it? Anyway, that’s what I’m getting from your comment…

    Boffbowsh — thank you for the helpful post. This was the ONLY recent post I could find about Rails and XMLRPC. I have one question for you:
    If you were to return the “file” as you do in your example, does xmlrpc4r automagically figure out that it is binary data and appropriately return it as base64? If I was returning an object, would it construct a struct for me? Are int’s, double’s, timestamps, etc all properly returned?

    p.witty@gmail.com

    10 Mar 09 at 02:55

  3. Hi All,
    Iam facing problems to get the response from webserver implemented in rails using XMLRPC.

    Below are my code details:
    ————————-
    client code:
    ———–
    require ‘xmlrpc/client’
    server = XMLRPC::Client.new2(“http://localhost/search/getStream/”)
    result=server.call(“getStream”,37).inspect
    puts result
    ——————

    serevrcode:
    ————-
    require ‘xmlrpc/server’
    server = XMLRPC::Server.new

    class SearchController response, :layout => false
    end
    end

    server.add_handler(“getStream”,SearchController.new)
    trap(“INT”) { server.shutdown }
    server.add_introspection
    server.serve
    ———————————–

    Below problems i am facing.
    1.could not able to recieve the aruments in server,so i have hardcoded to just chexk the functionality.
    2.As i am using xmlrpc/server i am thinking there is no change in the server code to get the response.If i am wrong please correct me .

    Can any one help me out from these problems.

    thanks
    Srikanth

    srikanth

    16 Jul 09 at 06:34

Leave a Reply

You must be logged in to post a comment.