Framework:sb JSON RPC2
From Surebert wiki
Contents |
Overview
Availabilty: sb 1.1+
Surebert's JSON_RPC2 client and server were created to allow you to call remote PHP procedures directly from javascript on the clientside. This is based on the spec proposal at http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal
sb_JSON_RPC2_Client
Used to send a sb_JSON_RPC2_Request instance to a sb_JSON_RPC2_Server server.
Calling a remote method from a sb_JSON_RPC_Server with PHP
To send a request to an sb_JSON_RPC2_Server with PHP, first create a sb_JSON_RPC2_Client instance
php code
//create a new client($host); - timeout and port are optional $client = new sb_JSON_RPC2_Client('http://example.com/json/server'); //call the remote method as though it is a method of your client. $response = $client->add(1,2); print_raw($response);
Using $client->dispatch
You can also dispatch a request using the client's dispatch method which accepts a sb_JSON_RPC2_Request instance as its only argument. Here we are calling the remote procedure add with the params 1 and 2. Using ->dispatch returns a full sb_JSON_RPC2_Response instance with the appropriate result or error property. When more extreme performance is required, this may be a better is a better option.
php code
$response = $client->dispatch(new sb_JSON_RPC2_Request('add', Array(1, 2))); print_raw($response);
Sending cookies to the server
You can pass cookies to the JSON server using add_cookie
php code
$client->add_cookie(Array('one' => 'two'));
Logging Requests/Responses
set a logger if you want to log (optional)
javascript code
$client->set_logger(new sb_Logger_FileSystem());
Debugging
While you can debug to a log, you can also debug directly to output buffer so that any data returned is shown.
javascript code
$client->sdebug = true;
Use Encryption
sb_JSON_RPC2_Client and Server can encrypt communication using mcrypt. In order for it to work, both client and server must use the same key.
javascript code
//use encryption for transfer, pass the same key the server is using $client->use_encryption($key);
PHP serializing response body
As of verison 1.2 sb_JSON_RPC2_Client and Server can serialize the response body as PHP before json encoding in order to preserve hashes as arrays. Otherwise they are converted to objects during json encode, which might not be ideal. The server will automagically server this way if the client requests it.
javascript code
//force server to serialize response as PHP $client->php_serialize_response = true;
Finding out what methods a sb_JSON_RPC2_Server provides
To find out what methods a server provides, call the remote procedure "get_methods". It is available by default on any sb_JSON_RPC2_Server instance. It returns an object with the methods available and any notes from your phpDocumentor code. For this reason it is critical to serve well-documented functions and methods.
Some servers may have this function turned off for security reasons.
php code
//create a new client $client = new sb_JSON_RPC2_Client('http://example.com/json/server'); //dispatch the request to a url, if you want to debug change false to true $response = $client->get_methods(); print_r($response);
The above remote procedure call would return the following:
text code
stdClass Object
(
[get_methods] =>
/**
* Get the methods available for this sb_JSON_RPC2_Server instance
* @return array
*/
[drop_punctuation] =>
/**
* An example function to serve which drop non letters or numbers from a string
* @param $str The string to strip
* @return string The string minus any non letters or numbers or _
*/
[add] => /**
* Adds two numbers together x+y
* @param $x integer
* @param $y integer
* @return integer
*/
[subtract] => /**
* Subtract two numbers x-y
* @param $x integer
* @param $y integer
* @return integer
*/
[multiple] => /**
* Mutliplies two numbers x*y
* @param $x integer
* @param $y integer
* @return integer
*/
[divide] => /**
* Divides two numbers x/y or throws JSON_RPC2_Error if divided by 0
* @param $x integer
* @param $y integer
* @return float
*/
[dance] => /**
* @param mixed $v unlimited number of variables to display with var_dump()
* @return string
*/
)
Once you know the methods you can request the phpdoc for a single method with
php code
//create a new client $client = new sb_JSON_RPC2_Client('http://example.com/json/server'); //dispatch the request to a url, if you want to debug change false to true $response = $client->get_phpdoc('some_method'); print_r($response);
sb_JSON_RPC2_Server
Handles sb_JSON_RPC2_Request and returns a json_encoded sb_JSON_RPC2_Response. See below for usage.
Creating a Server
A sb_JSON_RPC2_Server can serve a function, a class's methods, an object instance's methods or a mix of all three
php code
$server = new sb_JSON_RPC2_Server(); //optionally set the logger for debugging $server->set_logger(new sb_Logger_FileSystem()); //process the request echo $server->handle();
By default a server's serve method listens for the JSON_RPC request in the raw post data php://input. If you would like to test a specific request, you can pass the json string to the server's serve() method.
php code
$server = new sb_JSON_RPC2_Server(); echo $server->handle('{"method":"add","params":[1,2],"id":"abc123"}');
Setting the methods served
Serving a single function
Here we are setting the server to serve a function. The function add will be remotely available through the server and the params argument of the request will be sent to them as arguments
php code
/** * Adds two numbers together x+y * @param $x integer * @param $y integer * @return integer */ function add($x, $y){ return $x+$y; } $server = new sb_JSON_RPC2_Server(); $server->serve_function('add'); echo $server->handle();
Serving a class with static methods
Here we are setting the server to serve a class's static methods. Both of Math's add and substract methods will be remotely available through the server and the params argument of the request will be sent to them as arguments
php code
class Math{ /** * Adds two numbers together x+y * @param $x integer * @param $y integer * @return integer */ public static function add($x, $y){ return $x+$y; } /** * Subtract two numbers x-y * @param $x integer * @param $y integer * @return integer */ public static function substract($x, $y){ return $x-$y; } } $server = new sb_JSON_RPC2_Server(); $server->serve_class('Math'); echo $server->handle();
Serving an object instance
Here we are setting the server to serve an object instance's methods complete with reference to $this. Both of Math's add and substract methods will be remotely available through the server and the params argument of the request will be sent to them as arguments. Only the public methods are served.
php code
class Person{ public $dname; /** * @param string $to Who to say hello to * @return string The greeting */ public function say_hello($to){ return 'Hello '.$to.' I am '.$this->name; } } $user = new Person(); $user->dname = 'Visco, Paul'; $server = new sb_JSON_RPC2_Server(); $server->serve_instance($user); echo $server->handle();
Serving Mixed Methods
You can also set the server to serve a hodge podge of different methods from functin, classes and instances or even rename what the method is called by
php code
$server = new sb_JSON_RPC2_Server(); $server->add_methods(Array( //serve a function called drop_punctuation 'drop_punctuation' => 'drop_punctuation', //serve Maths static add method as a method simply called + 'add' => Array('Math', 'add'), //serve the person instance's say_hello method 'say_hello' => Array($person, 'say_hello') )); echo $server->handle();
Removing methods from the server
If you want to simply remove a method or methods form the server temporarily or you wish to serve an object instance accept for certain methods you can use $server->remove_method($str); or $server->remove_methods($array);
php code
$server->remove_method('some_method'); //or multiple $server->remove_methods(Array('some_method', 'some_other_method');
Disable get_methods() support
IF YOU DO NOT WANT YOUR SERVER TO DISPLAY THE METHODS AVAILABLE WITH get_methods(), redefine the get_methods() method for your server.'
Using a function
php code
function get_methods(){ return ''; } $server->add_methods(Array( //serve a function called drop_punctuation 'get_methods' => 'get_methods' ));
Using a function
php code
class Person{ public $dname; /** * @param string $to Who to say hello to * @return string The greeting */ public function say_hello($to){ return 'Hello '.$to.' I am '.$this->name; } public function get_methods(){ return false; } } $user = new Person(); $user->dname = 'Visco, Paul'; $server = new sb_JSON_RPC2_Server(); $server->serve_instance($user); echo $server->handle();
JSON RPC2 Server View
The easiest way to create a sb_JSON_RPC2_Server is to use an sb_View_JSON_RPC2_Server view. Every method of the view is served as a method. Say this was in /views/server/ServerView.php
php code
<?php class ServerView extends sb_View_JSON_RPC2_Server{ public function hello_world(){ return 'hello world'; } } ?>
You could then call it with a client as such
php code
$client = new sb_JSON_RPC2_Client('http://yoursite.com/server'); $client->hello_world();
HTTP Status Headers
By default a sb_JSON_RPC2_Server serves the appropriate HTTP status header with the response, see the table above. If you would like to surpress the headers from being sent set the instance's surpress_http_status to true; You may have to do this for certain clients that won't read the message body if a status other than 200 is returned, e.g. 400, 404, 500
php code
$server->suppress_http_status = true;
GZ Compression
A sb_JSON_RPC2_Server instance can serve the json data gzipped. This is an excellent way to save bandwith for larger data transfers. You can set the gz compression level by passing a level 0-9 to the $server->use_gz_encoding(3); method
php code
$server->use_gz_encoding(6);
Use Encryption
sb_JSON_RPC2_Client and Server can encrypt communication using mcrypt. In order for it to work, both client and server must use the same key. javascript code
php code
//use encryption for transfer, pass the same key the server is using $server->use_encryption($key);
sb_JSON_RPC2_Request
Used to model a JSON RPC2 request
Properties
- method - A String containing the name of the procedure to be invoked.
- params - An Array or Object, that holds the actual parameter values for the invocation of the procedure. Can be omitted if empty.
- id - A request identifier, will be returned with the respose
sb_JSON_RPC2_Response
Used to model a JSON RPC2 response
Properties
- result - Required on success, omitted on failure. The Value that was returned by the procedure. Its contents is entirely defined by the procedure. This member MUST be entirely omitted if there was an error invoking the procedure.
- error - an sb_JSON_RPC2_Error Required on error, omitted on success. An Object containing error information about the fault that occurred before, during or after the call. This member MUST be entirely omitted if there was no such fault.
- id - The same id as in the Request it is responding to. If there was an error before detecting the id in the Request, it MUST be Null.
sb_JSON_RPC2_Error
Used to model a JSON RPC2 error
Properties
- mesage - A short description of the error. The message SHOULD be limited to a concise single sentence.
- data - Additional information, may be omitted. Its contents is entirely defined by the application (e.g. detailed error information, nested errors etc.).
- code - A Number that indicates the actual error that occurred.
| code | message | meaning | HTTP STATUS returned with response |
|---|---|---|---|
| -32700 | Parse error | Invalid JSON. An error occurred on the server while parsing the JSON text. | 500 |
| -32600 | Invalid Request | The received JSON not a valid JSON-RPC Request. | 400 |
| -32601 | Method not found. | The requested remote-procedure does not exist / is not available. | 404 |
| -32602 | Invalid params | Invalid method parameters | 500 |
| -32603 | Internal error | Internal JSON-RPC error. | 500 |
| -32099..-32000 | Server error | Reserved for implementation-defined server-errors. | 500 |
The error-codes -32768 .. -32000 (inclusive) are reserved for pre-defined errors.
Surebert Toolkit Javascript client for sb_JSON_RPC_Server
Information about using the surebert toolkit to make a JSON RPC2 call with javascript view the following: Toolkit:json:rpc2