Skip to content
This repository

Light, concurrent RPC framework for PHP & C (java, python etc will be supported soon)

branch: master
Octocat-spinner-32 packagers Refactor Yar, make the arch more clear for the persistent link January 08, 2013
Octocat-spinner-32 tests Fixed test July 15, 2013
Octocat-spinner-32 tools fix yar_debug.inc bug January 06, 2014
Octocat-spinner-32 transports Fixed build with libcurl-7.12 February 12, 2014
Octocat-spinner-32 travis Add Travis August 26, 2012
Octocat-spinner-32 .gitignore Initial commit June 15, 2012
Octocat-spinner-32 .travis.yml Update .travis.yml August 26, 2012
Octocat-spinner-32 CREDITS change name to Yar , and merge some new changes June 19, 2012
Octocat-spinner-32 EXPERIMENTAL change name to Yar , and merge some new changes June 19, 2012
Octocat-spinner-32 LICENSE Fixed ISSUE #6 Add License file July 21, 2013
Octocat-spinner-32 README.md Update README November 19, 2013
Octocat-spinner-32 config.m4 Fix config.* January 02, 2014
Octocat-spinner-32 config.w32 Fix config.* January 02, 2014
Octocat-spinner-32 package2.xml Enable msgpack prompt in package.xml January 07, 2014
Octocat-spinner-32 php_yar.h back to dev January 02, 2014
Octocat-spinner-32 yar.c fixed version constant name January 14, 2014
Octocat-spinner-32 yar.php change name to Yar , and merge some new changes June 19, 2012
Octocat-spinner-32 yar_client.c Another one December 31, 2013
Octocat-spinner-32 yar_client.h Fixed build before 5.2.6 January 08, 2014
Octocat-spinner-32 yar_exception.c Fix memory leak, since the set_error dup errmsg now January 10, 2013
Octocat-spinner-32 yar_exception.h Change DEBUG info to E_WARNING July 15, 2013
Octocat-spinner-32 yar_packager.c Improve debug info January 10, 2013
Octocat-spinner-32 yar_packager.h Refactor Yar, make the arch more clear for the persistent link January 08, 2013
Octocat-spinner-32 yar_protocol.c Fixed header file December 31, 2013
Octocat-spinner-32 yar_protocol.h More tests January 12, 2013
Octocat-spinner-32 yar_request.c More tests January 12, 2013
Octocat-spinner-32 yar_request.h More tests January 12, 2013
Octocat-spinner-32 yar_response.c update test scripts January 11, 2013
Octocat-spinner-32 yar_response.h Refactor Yar, make the arch more clear for the persistent link January 08, 2013
Octocat-spinner-32 yar_server.c Add debug info January 02, 2014
Octocat-spinner-32 yar_server.h Refactor Yar, make the arch more clear for the persistent link January 08, 2013
Octocat-spinner-32 yar_transport.c Refactor Yar, make the arch more clear for the persistent link January 08, 2013
Octocat-spinner-32 yar_transport.h Fix ZTS build January 10, 2013
Octocat-spinner-32 yar_transports.h Refactor Yar, make the arch more clear for the persistent link January 08, 2013
README.md

Yar - Yet Another RPC framework for PHP

Build Status

Light, concurrent RPC framework for PHP(c, java etc will be supported soon)

Requirement

  • PHP 5.2+
  • Curl
  • Json
  • Msgpack (Optional)

Introduction

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.

Features

  • 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)
  • Detailed debug informations

Install

Install Yar

Yar is an PECL extension, thus you can simply install it by:

pecl install yar

Compile Yar in Linux

$/path/to/phpize
$./configure --with-php-config=/path/to/php-config/
$make && make install

Install Yar with msgpack

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

Runtime Configure

  • yar.timeout //default 5000 (ms)
  • yar.connect_timeout //default 1000 (ms)
  • yar.packager //default "php", when built with --enable-msgpack then default "msgpack", it should be one of "php", "json", "msgpack"
  • yar.debug //default Off
  • yar.expose_info // default On, whether output the API info for GET requests
  • yar.content_type // default "application/octet-stream"
  • yar.allow_persistent // default Off

NOTE yar.connect_time is a value in milliseconds, and was measured in seconds in 1.2.1 and before.

Constants

  • YAR_VERSION
  • YAR_OPT_PACKAGER
  • YAR_OPT_PERSISTENT
  • YAR_OPT_TIMEOUT
  • YAR_OPT_CONNECT_TIMEOUT

Server

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 some_method($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:

yar service info page

Client

It's very easy for a PHP client to call remote RPC:

Synchronous call

<?php
$client = new Yar_Client("http://host/api/");
/* the following setopt is optinal */
$client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, 1);

/* call remote service */
$result = $client->some_method("parameter");
?>

Concurrent call

<?php
function callback($retval, $callinfo) {
     var_dump($retval);
}

function error_callback($type, $error, $callinfo) {
    error_log($error);
}

Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback");
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"));   // if the callback is not specificed, 
                                                                               // callback in loop will be used
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", "error_callback", array(YAR_OPT_PACKAGER => "json"));
                                                                               //this server accept json packager
Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", "error_callback", array(YAR_OPT_TIMEOUT=>1));
                                                                               //custom timeout 

Yar_Concurrent_Client::loop("callback", "error_callback"); //send the requests, 
                                                           //the error_callback is optional
?>

Protocols

Yar Header

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

Packager Header

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.

Request

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
)

Server

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
)
Something went wrong with that request. Please try again.