Showing posts with label XMLRPC. Show all posts
Showing posts with label XMLRPC. Show all posts
0

GWT XMLRPC

On my previous work on XMLRPC, I had work with C# and PHP.
This morning I decide to try a library written for GWT.
The project can be found at:

http://code.google.com/p/xmlrpc-gwt/

Since there is no compiled .jar files, so I need create the .jar file myself.
Since I just used Eclipse for 2 weeks (before this using Netbeans + GWT4NB), it take me a long way just to create the .jar file. Actually to create .jar file is very simple step and require less than a minute.

Simply put the library inherits setting in the project.

<inherits name='com.fredhat.gwt.xmlrpc.XMLRPC'>

I just modify the sample given on the project's wiki and call the add function in my previous XMLRPC server sample.


XmlRpcClient client = new XmlRpcClient("http://127.0.0.1/xmlrpc/server.php");
String methodName = "add";
Object[] params = new Object[]{3, 4};
 
XmlRpcRequest<Integer> request = new XmlRpcRequest<Integer>(client, methodName, params, new AsyncCallback<Integer>() {
   public void onSuccess(Integer response) {
           // Handle integer response logic here
     Console.writeLine(response);
   }

   public void onFailure(Throwable response) {
           String failedMsg = response.getMessage();
           // Put other failed response handling logic here
           Console.writeLine(failedMsg);
   }
});
request.execute();


Done and it work just fine.
The .jar file can be found here.
0

PHP XML-RPC Client Simplified

In my previous for XML-RPC client helper, I suggested to create a client instance to make your methods exposed and developer friendly. But may be some of us are too lazy write all the wrapper code. There is solution for that.

In this case you still need to create client instance which extends XMLRPCClientHelper, but this time you don't need to write all the wrapper code. Just simply add __call overload methods.

It's easy but you need to remember the service API.

Here is the code:

<?php
class TestXMLRPCClientSimplified extends XMLRPCClientHelper {
    public function __call($name, $arguments) {
        return $this->sendRequest("$name", $arguments);
    }    
}
?>

0

PHP XML-RPC Client Helper

I wrote a helper for XMLRPC client.
I also added the automatic base64 type setting for bytes data.
Just need to create the client instance and supply the service URL, then you can start to call the service.

To make you client methods is expose and developer friendly, you can create your own client class which extends XMLRPCClientHelper.

<?php
class TestXMLRPCClient extends XMLRPCClientHelper {

    /**
     * Add two number
     * @param <int> $A
     * @param <int> $B
     * @return <int>
     */
    public function add($A, $B) {
        $params = array($A, $B);
        return $this->sendRequest("add", $params);
    }
}
?>


Here is the simple example :

$url = "http://192.168.56.1:5678/service.rem";
$client = new TestXMLRPCClient();
$client->setURL($url);
$result=$client->add(1,4);  //test add
print "Add Result: $result <br>\n";

It also support the exception when there is any error occurs it will throw the exception.So you just need to use try and catch to handle that.

XMLRPCClientHelper.php. This file also included in my training materials on my previous post.

<?php

/**
 * This helper class help to create a simple XML-RPC client
 * @author Mohamad Fairol Zamzuri B Che Sayut <mfz_peyo@yahoo.com>
 */
class XMLRPCClientHelper {

    private $url;

    /**
     * Get URL
     */
    public function getURL() {
        return $this->url;
    }

    /**
     * Set URL
     * @param <string> $url URL
     */
    public function setURL($url) {
        $this->url = $url;
    }

    /**
     * Send RPC request
     * @param <string> $methodname method name
     * @param <array> $parameters parameters
     */
    public function sendRequest($methodname, $parameters) {
        for ($i = 0; $i < count($parameters); $i++) {
            if (mb_detect_encoding($parameters[$i]) === false) {
                xmlrpc_set_type(&$parameters[$i], "base64");
            }
        }
        $request = xmlrpc_encode_request($methodname, $parameters);
        $context = stream_context_create(array('http' => array(
                        'method' => "POST",
                        'header' => "Content-Type: text/xml",
                        'content' => $request
                        )));
        $file = file_get_contents($this->url, false, $context);
        $response = xmlrpc_decode($file);
        if (is_array($response) && xmlrpc_is_fault($response)) {
            throw new Exception($response['faultString'], $response['faultCode']);
        }
        return $response;
    }

}

?>

0

PHP XML-RPC Server Helper

I wrote a XMLRPCServerHelper to help me to create XML-RPC service in PHP.
It's easy to use and you just need to set the classname of service and all the methods will be extracted automatically using ReflectionClass.

The example of the server :

<?php
error_reporting(E_ERROR | E_PARSE);
require_once("autoload.php");

$server = new XMLRPCServerHelper();
$server->setClassName("TestXMLRPCService");
$answer = $server->handle();
header('Content-Type: text/xml');
print($answer);
?>


The service can be access from your normal webserver url.
To generate php client class, just simply add ?phpwrapper to the url. E.g :

 http://localhost/xmlrpc/server.php?phpwrapper


XMLRPCServerHelper.php . This file also incuded in my training materials on my previous post.

<?php

/**
 * This helper class help to create XML-RPC server
 */
class XMLRPCServerHelper {

    /**
     * Server handler holder
     * @var <Object> Server handler holder
     */
    private $serverHandler;
    /**
     * Class name holder
     * @var <string> Class name holder
     */
    private $classname;
    /**
     * External function list holder
     * @var <array>  External function list holder
     */
    private $externalFunctions;

    /**
     * Contructor
     */
    public function __construct() {
        $this->serverHandler = xmlrpc_server_create();
        $this->externalFunctions = array();
    }

    /**
     * Set object class.
     * All class methods will be extracted and registerd automatically
     * @param <Object> $class
     */
    public function setClassName($classname) {
        $this->classname = $classname;
        $reflection = new ReflectionClass($classname);
        $methods = $reflection->getMethods();
        $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        for ($i = 0; $i < count($methods); $i++) {
            $reflectmethod = $methods[$i];
            $methodname = $reflectmethod->name;
            $reflectparams = $reflectmethod->getParameters();
            if (count($reflectparams) > 0) {
                for ($j = 0; $j < count($reflectparams); $j++) {
                    $methodparams[] = $reflectparams[$j]->name;
                }
            } else {
                $methodparams = array();
            }
            $this->registerMethod($methodname, array(&$classname, $methodname), $methodparams);
        }
    }

    /**
     * Generate client wrapper
     */
    private function generatePHPClientWrapper() {
        $classfunctions = "";
        $reflection = new ReflectionClass($this->classname);
        $methods = $reflection->getMethods();
        $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        for ($i = 0; $i < count($methods); $i++) {
            $reflectmethod = $methods[$i];
            $methodname = $reflectmethod->name;
            $reflectparams = $reflectmethod->getParameters();
            $funcParams = "";
            $funcContent = "";
            if (count($reflectparams) > 0) {
                for ($j = 0; $j < count($reflectparams); $j++) {
                    //$funcContent.= "\$params[] = \$" . $reflectparams[$j]->name . ";\n";
                    if ($funcParams != "") {
                        $funcParams.=",";
                    }
                    $funcParams.='$' . $reflectparams[$j]->name;
                }
                $funcContent = "\$params = array($funcParams);\n";
            } else {
                $funcContent = "\$params = array();\n";
            }

            $classfunctions.="public function $methodname($funcParams) {\n";
            $classfunctions.=$funcContent;
            $classfunctions.="return \$this->sendRequest(\"$methodname\", \$params);\n";
            $classfunctions.="}\n\n";
        }

        $wrapper = "<pre>class " . $this->classname . "XMLRPCClient extends XMLRPCClientHelper {\n";
        $wrapper .= "$classfunctions";
        $wrapper .= "}\n</pre>";
        return $wrapper;
    }

    /**
     * Register method
     * @param <string> $externalName class name
     * @param <Object> $function class pointer
     * @param <array> $parameterNames parameters name
     */
    public function registerMethod($externalName, $function, $parameterNames) {
        if ($function == null) {
            $function = $externalName;
        }
        xmlrpc_server_register_method($this->serverHandler, $externalName, array(&$this, 'callMethod'));
        $this->externalFunctions[$externalName] = array('function' => $function, 'parameterNames' => $parameterNames);
    }

    /**
     * Invoke class method
     * @param <string> $functionName method name
     * @param <array> $parametersFromRequest parameters
     * @return <variant> function call result
     */
    public function callMethod($functionName, $parametersFromRequest) {
        if ($functionName == "generatePHPClientWrapper") {
            return $this->generatePHPClientWrapper();
        }

        $function = $this->externalFunctions[$functionName]['function'];
        $parameterNames = $this->externalFunctions[$functionName]['parameterNames'];
        return call_user_func_array($function, $parametersFromRequest);
    }

    /**
     * Handle server call
     * @return <variant>  function call result
     */
    public function handle() {
        $bWrapper = false;
        foreach ($_GET as $key => $value) {
            if ($key == "phpwrapper") {
                $bWrapper = true;
                continue;
            }
        }

        if ($bWrapper) {
            print $this->generatePHPClientWrapper();
            exit();
        }
        return xmlrpc_server_call_method($this->serverHandler, file_get_contents('php://input'), null);
    }

}

?>

XMLRPC Training (C# and PHP)

Today, I'm going to conduct a simple training on XML-RPC at my previous company.
You can access to the training materials on my googleDocs.


Presentation Slide
PHP source code
C# source code
 
Copyright © peyotest