260 likes | 746 Views
XML-RPC . XML-RPC Architecture. Client-server architecture Client executes RPCs on the server Server has 3 components: The main thread The XML-RPC server (takes place of stubs) One or more RPC handlers Server processes each RPC by calling the corresponding RPC handler. XML-RPC Server.
E N D
XML-RPC Architecture • Client-server architecture • Client executes RPCs on the server • Server has 3 components: • The main thread • The XML-RPC server (takes place of stubs) • One or more RPC handlers • Server processes each RPC by calling the corresponding RPC handler
XML-RPC Server Client Server RPC Handler XML-RPC Architecture HTTP
XML-RPC Types • 4-byte signed integer • Boolean • String • Double • Date/Time (not fully ISO 8601 compatible!) • No time zone information • Binary (base-64) • Arrays of any of these types • Structures containing these types • Map of element names to types/values
XML-RPC Libraries • C++: xmlrpc-c • http://xmlrpc-c.sourceforge.net • Only installed on ccc1 right now • Java: Apache XML-RPC • http://ws.apache.org/xmlrpc • Required: Apache commons-codec library • http://jakarta.apache.org/commons/codec • Use on any machine except ccc1 (no Java 1.5)
Client-Side XML-RPC • 2 types of XML-RPCs • Synchronous • Asynchronous • What is the difference? • What are the advantages and disadvantages of each?
Synchronous XML-RPCs • Client executes RPC on server • Client blocks until the RPC returns • Server returns a generic object/type • C++ (xmlrpc-c) Library • xmlrpc_c::value • Java (Apache) Library • Object • Client must know what type to expect • Cast generic type to expected type
Asynchronous XML-RPCs • Client must define a call-back object • Method to handle RPC success • Method to handle RPC failure/error • Client makes asynchronous RPC • Simply spawns a new thread for the RPC • Returns immediately • When the RPC has finished, one of the call-back methods will be executed • Cast return value to expected type
Executing an XML-RPC • 1. Build a list of RPC parameters • Analogous to function/method parameters • 2. Initialize the RPC • Name of the RPC • URL (it’s HTTP) of the XML-RPC server • http://address:port/RPC2 • 3. Execute the RPC • 4. Handle errors • 5. Interpret return value
Build a List of RPC Parameters • C++ xmlrpc_c::paramList params; params.add( xmlrpc_c::value_string(“Hello server.”)); • Java java.util.Vector params = new Vector(); params.add(new String(“Hello server.”));
Initialize the RPC • C++ xmlrpc_c::clientXmlTransport_libwww xlmrpcTransport; xmlrpc_c::client_xml xmlrpcClient( &xmlrpcTransport); xmlrpc_c::rpcPtr xmlrpc( “server.sayHello”, params); xmlrpc_c::carriageParm_libwww0 cParm( “http://127.0.0.1:9382/RPC2”);
Initialize the RPC • Java XmlRpcClient client = null; try { client = new XmlRpcClient( “http://127.0.0.1:9382/RPC2”); } catch (MalformedURLException e) { System.err.println(e); }
Execute the RPC • C++ try { xmlrpc->call(&client, &cParm); } catch (std::exception const e) { cerr << “Connection refused.” << endl; }
Execute the RPC • Java try { Object returnValue = client.execute( “server.sayHello”, params); } catch (XmlRpcException e) { System.err.println(e); // some RPC problem } catch (IOException e) { System.err.println(“Connection refused.”); }
Handle errors • C++ if (xmlrpc->isSuccessful() == false) { if (xmlrpc->isFinished() == true) { xmlrpc_c::fault f = xmlrpc->getFault(); if (f.getCode() == 0) {…} // exception else {…} // unexpected error } else {…} // unexpected error – can’t get fault }
Interpret Return Value • C++ if (xmlrpc->isSuccessful() == true) { xmlrpc_c::value v = xmlrpc->getResult(); xmlrpc_c::value_string rpcstr = (xmlrpc_c::value_string) v; std::string text = (std::string) rpcstr; }
Interpret Return Value • Java // The return value of the RPC was stored // in returnValue, which is of type Object. try { String text = (String) returnValue; } catch (ClassCastException e) { // returnValue was not a String. // It could have been an Exception. }
Creating an XML-RPC Server • 1. Define one or more RPC handlers • C++: Subclass xmlrpc_c::method • Java: Create a new public class • 2. Initialize the library’s server object • Provide port number on which to listen • 3. Add RPC handlers to the server • Library-specific call • 4. Start the server • Optionally create new thread for server
Define RPC Handlers • C++ class HelloMethod : public xmlrpc_c::method { public: void execute(xmlrpc-c::paramList const& params, xmlrpc_c::value* const retvalP) { *retvalP = xmlrpc_c::value_string( “Hello client.”); } };
Define RPC Handlers • Java public class RPCHandler { // All public methods in this class are // RPC handlers public String sayHello(String param) { return new String(“Hello client.”); } }
Initialize the Server • C++ xmlrpc_c::registry reg; xmlrpc_c::serverAbyss server; • Java WebServer server = null; try { server = new WebServer(9382); } catch (Exception e) { System.err.println(e); }
Add RPC Handlers • C++ xmlrpc_c::methodPtr const helloMethod( new HelloMethod); reg.addMethod(“server.sayHello”, helloMethod); server = xmlrpc_c::serverAbyss(reg, 9382, “xmlrpc.log”);
Add RPC Handlers • Java server.addHandler( “server”, new RPCHandler() ); // RPC names will be “server.” followed by // the name of a public method in // RPCHandler.
Start the Server • C++ // Runs in current thread. server.run(); • Java // Runs in new thread. server.start();