Light, concurrent RPC framework for PHP(c, java etc will be supported soon)
- PHP 5.2+
- Curl
- Json
- Msgpack (Optional)
Yar is a RPC framework which aims to provide a simple and easy way to do communication between PHP applications
It has the ability to concurrently call multiple remote services.
- Fast, Easy, Simple
- Concurrent RPC calls
- Multiple data packager supported (php, json, msgpack built-in)
- Multiple transfer protocols supported (http implemented, tcp/unix will be supported later)
- Authentication
- Detailed debug informations
Yar is an PECL extension, thus you can simply install it by:
pecl install yar
$/path/to/phpize
$./configure --with-php-config=/path/to/php-config/
$make && make install
first you should install msgpack-ext
pecl install msgpack
or , you can get the github source here: https://github.com/msgpack/msgpack-php
then:
$phpize
$configure --with-php-config=/path/to/php-config/ --enable-msgpack
$make && make install
- yar.timeout //default 5
- yar.connect_timeout //default 1
- yar.packger //default "php", it should be one of "php", "json", "msgpack"
- yar.debug //default Off
It's very easy to setup a Yar HTTP RPC Server
<?php
class API {
/**
* the doc info will be generated automatically into service info page.
* @params
* @return
*/
public function api($parameter, $option = "foo") {
}
protected function client_can_not_see() {
}
}
$service = new Yar_Server(new API());
$service->handle();
?>
Usual RPC calls will be issued as HTTP POST requests. If a HTTP GET request is issued to the uri, the service information (commented section above) will be printed on the page:
It's very easy for a PHP client to call remote RPC:
<?php
$client = new Yar_Client("http://host/api/");
$result = $client->api("parameter);
?>
<?php
function callback($retval, $callinfo) {
var_dump($retval);
}
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "api", array("parameters"), "callback");
Yar_Concurrent_Client::loop(); //send
?>
Setting up a server that requires authentication is also rather easy. You just have to declare a method called "__auth" in the server class.
<?php
class API {
/**
* if this method return false, then the rpc call will be denied
*/
public function __auth($user, $password) {
}
/**
* the doc info will be generated automatically into service info page.
* @params
* @return
*/
public function api($parameter, $option = "foo") {
}
protected function client_can_not_see() {
}
}
$service = new Yar_Server(new API());
$service->handle();
?>
Consequently, the client code should be change to :
<?php
$client = new Yar_Client("http://username:password@host/api/");
$result = $client->api("parameter);
?>
Since Yar will support multi transfer protocols, so there is a Header struct, I call it Yar Header
#ifdef PHP_WIN32
#pragma pack(push)
#pragma pack(1)
#endif
typedef struct _yar_header {
unsigned int id; // transaction id
unsigned short version; // protocl version
unsigned int magic_num; // default is: 0x80DFEC60
unsigned int reserved;
unsigned char provider[32]; // reqeust from who
unsigned char token[32]; // request token, used for authentication
unsigned int body_len; // request body len
}
#ifndef PHP_WIN32
__attribute__ ((packed))
#endif
yar_header_t;
#ifdef PHP_WIN32
#pragma pack(pop)
#endif
Since Yar also supports multi packager protocl, so there is a char[8] at the begining of body, to identicate which packager the body is packaged by.
When a Client request a remote server, it will send a struct (in PHP):
<?php
array(
"i" => '', //transaction id
"m" => '', //the method which being called
"p" => array(), //parameters
)
When a server response a result, it will send a struct (in PHP):
<?php
array(
"i" => '',
"s" => '', //status
"r" => '', //return value
"o" => '', //output
"e" => '', //error or exception
)