Upload
pearl-williams
View
260
Download
1
Embed Size (px)
Citation preview
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 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.”));
• Javajava.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
• JavaXmlRpcClient 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
• Javatry {
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) {…} // exceptionelse {…} // 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
• Javapublic class RPCHandler {
// All public methods in this class are // RPC handlerspublic String sayHello(String param) {
return new String(“Hello client.”);}
}
Initialize the Server
• C++xmlrpc_c::registry reg;xmlrpc_c::serverAbyss server;• JavaWebServer 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
• Javaserver.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();