Beispiel für XML-RPC Server und Client
Server
Um einen XmlRpc Server zu betreiben muss man den HTTP-Server starten und einen Handler installieren. "/RPC2" ist die Default-URL für XmlRpc. Der Code enthält ein xmlRpcHandler, ein Method-Handler und eine eigene Test-Methode.
#uses "CtrlHTTP"
#uses "CtrlXmlRpc"
#uses "xmlrpcHandlerCommon.ctl"
#uses "CtrlZlib"
int HTTP_PORT = 80;
const int HTTPS_PORT = 0;
// To enable https, set this to 443
main()
{
//Start the HTTP Server
if (httpServer(false, HTTP_PORT, HTTPS_PORT) < 0)
{
DebugN("ERROR: HTTP-server can't start. --- Check license");
return;
}
//Start the XmlRpc Handler
httpConnect("xmlrpcHandler", "/RPC2");
}
mixed xmlrpcHandler(const mixed content, string user, string ip, dyn_string ds1, dyn_string ds2, int connIdx)
{
string sMethod, sRet;
dyn_mixed daArgs;
mixed methodResult;
mixed xmlResult;
string cookie = httpGetHeader(connIdx, "Cookie");
int ret;
dyn_errClass derr;
//Decode content
ret = xmlrpcDecodeRequest(content, sMethod, daArgs);
derr = getLastError();
if (ret < 0 || dynlen(derr)>=1)
{
throwError(derr);
//Output Error
derr = xmlRpcMakeError(PRIO_SEVERE, ERR_SYSTEM, ERR_PARAMETER, "Error parsing xml-rpc stream", "Method: "+sMethod);
throwError(derr);
return xmlrpcReturnFault(derr);
}
//Start own method handler
methodResult = methodHandlerOwn(sMethod, daArgs, user,cookie);
derr = xmlRpcGetErrorFromResult(methodResult);
/* Get error from result if error occurred */
if (dynlen(derr) > 0) //Error occurred
{
throwError(derr);
// return fault
//Encode Error
return makeDynString(xmlrpcReturnFault(derr), "Content-Type: text/xml");
}
sRet = xmlrpcReturnSuccess(methodResult);
//Encode result
//Compress the result if the other side allows it
if
( strlen(sRet) > 1024 && strpos(httpGetHeader(connIdx, "Accept- Encoding"),"gzip") >= 0)
{
//Return compressed content
blob b;
gzip(sRet, b);
xmlResult = makeDynMixed (b, "Content-Type: text/xml", "Content-Encoding: gzip");
}
else
{
//Return plain content
xmlResult = makeDynString(sRet, "Content-Type: text/xml");
}
return xmlResult;
}
mixed methodHandlerOwn(string sMethod, dyn_mixed &asValues, string user, string cookie)
{
switch (sMethod)
{
case "wccoa.own.testmethod" :
return xmlrpc_wccoa_own_testmethod(sMethod, asValues);
default :
return methodHandlerCommon(sMethod, asValues, user, cookie);
}
}
private mixed xmlrpc_wccoa_own_testmethod(string sMethod, dyn_mixed values)
{
mixed res;
string name;
//Check parameters
if (dynlen(values) >= 2)
return xmlRpcMakeError(PRIO_SEVERE, ERR_CONTROL, ERR_INVALID_ARGUMENT, sMethod, ""+values);
//Magic Code:
name = values[1];
res = "Hello World"+name;
return res;
}
Client
Baut eine Verbindung zum Server auf, ruft die Funktion auf dem Server auf und schließt die Verbindung zum Server:
#uses "CtrlXmlRpc"
main()
{
string id = "servID";
string func = "wccoa.own.testmethod";
dyn_mixed args = makeDynString("World");
mixed res;
string host = "localhost";
int port = "80";
bool secure = FALSE;
xmlrpcClient();
xmlrpcConnectToServer(id, host, port, secure);
xmlrpcCall(id, func, args, res);
DebugN("Result of XmlRpc call", res);
xmlrpcCloseServer(id);
}