IOT>> yar>> 返回
项目作者: laruence

项目描述 :
Light, concurrent RPC framework for PHP & C
高级语言: C
项目地址: git://github.com/laruence/yar.git
创建时间: 2012-06-15T07:42:26Z
项目社区:https://github.com/laruence/yar

开源协议:Other

下载


Yar - Yet Another RPC framework for PHP

Build status Build Status

Light, concurrent RPC framework for PHP(see also: Yar C framework, Yar Java framework)

Requirement

  • PHP 7.0+ (master branch))
  • PHP 5.2+ (php5 branch)
  • Curl
  • Json
  • Msgpack (Optional)

Introduction

Yar is a RPC framework which provides a simple and easy way to do communication between PHP applications, it also offers an ability of doing multiple calls to remote services concurrently.

Features

  • Fast, Easy, Simple
  • Concurrent RPC calls
  • Multiple data packager supported (php, json, msgpack built-in)
  • Multiple transfer protocols supported (http, https, TCP)
  • Detailed debug informations

Install

Install Yar

Yar is an PECL extension, could be installed simply by:

  1. pecl install yar

Compile Yar in Linux

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

Available instructions to configure are

  1. --with-curl=DIR
  2. --enable(disable)-msgpack
  3. --enable(disable)-epoll (require Yar 2.1.2)

Install Yar with msgpack

  1. Install msgpack for PHP extension:

    1. pecl install msgpack

    or for ubuntu user

    1. apt-get install msgpack-php

    or , you can get the github source here: https://github.com/msgpack/msgpack-php

  2. configuration:

    1. $phpize
    2. $configure --with-php-config=/path/to/php-config/ --enable-msgpack
    3. $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, which was measured in seconds before 1.2.1.

Constants

  • YAR_VERSION
  • YAR_OPT_PACKAGER
  • YAR_OPT_PERSISTENT
  • YAR_OPT_TIMEOUT
  • YAR_OPT_CONNECT_TIMEOUT
  • YAR_OPT_HEADER // Since 2.0.4
  • YAR_OPT_PROXY //Since 2.2.0
  • YAR_OPT_PROVIDER //Since 2.3.0
  • YAR_OPT_TOKEN //Since 2.3.0

Server

It’s very easy to setup a Yar HTTP RPC Server

  1. <?php
  2. class API {
  3. /**
  4. * the doc info will be generated automatically into service info page.
  5. * @params
  6. * @return
  7. */
  8. public function some_method($parameter, $option = "foo") {
  9. }
  10. protected function client_can_not_see() {
  11. }
  12. }
  13. $service = new Yar_Server(new API());
  14. $service->handle();
  15. ?>

Usual RPC calls are issued as HTTP POST requests.

If a HTTP GET request is issued to the uri(access the api address directly via a browser), the service information (commented section above) will be returned, like:

yar service info page

Custom server info

Since 2.3.0, Yar allows you to custom the output in above example by defining “__info” magic method:

  1. <?php
  2. class API {
  3. protected function __info($markup) {
  4. return "Hello world";
  5. }
  6. }

then If a HTTP GET request is issued, “hello world” will be sent instead.

Authentication

Since 2.3.0, Yar allows server to authentic client request by Provider/Token fileds in header, for achieve this, you should define a protected magic method named “__auth” in server side:

  1. <?php
  2. class API {
  3. protected function __auth($provider, $token) {
  4. return verify($provider, $token);
  5. }

NOTE __auth method should always be defined as protected

if a Yar server has auth defined, then auth will be called at the very first time for any request,

if __auth method return true, the request will be processed further, otherwise the request will be terminated by an error of “authentication failed”

in clent side, you can specific the provider/token by:

  1. <?php
  2. $client->setOpt(YAR_OPT_PROVIDER, "provider");
  3. $client->setOpt(YAR_OPT_TOKEN, "token");
  4. $client->call();

Client

It’s very simple for a PHP client to call remote RPC:

Synchronous call

  1. <?php
  2. $client = new Yar_Client("http://host/api/");
  3. /* the following setopt is optinal */
  4. $client->SetOpt(YAR_OPT_CONNECT_TIMEOUT, 1000);
  5. $client->SetOpt(YAR_OPT_HEADER, array("hd1: val", "hd2: val")); //Custom headers, Since 2.0.4
  6. /* call remote service */
  7. $result = $client->some_method("parameter");
  8. ?>

Concurrent call

  1. <?php
  2. function callback($retval, $callinfo) {
  3. var_dump($retval);
  4. }
  5. function error_callback($type, $error, $callinfo) {
  6. error_log($error);
  7. }
  8. Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback");
  9. Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters")); // if the callback is not specificed,
  10. // callback in loop will be used
  11. Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", "error_callback", array(YAR_OPT_PACKAGER => "json"));
  12. //this server accept json packager
  13. Yar_Concurrent_Client::call("http://host/api/", "some_method", array("parameters"), "callback", "error_callback", array(YAR_OPT_TIMEOUT=>1));
  14. //custom timeout
  15. Yar_Concurrent_Client::loop("callback", "error_callback"); //send the requests,
  16. //the error_callback is optional
  17. ?>

Persistent call

After Yar 2.1.0, if YAR_OPT_PERSISTENT is set to true, then Yar is able to use HTTP keep-alive to speedup repeated calls to a same address, the link will be released at the end of the PHP request lifecycle.

  1. <?php
  2. $client = new Yar_Client("http://host/api/");
  3. $client->SetOpt(YAR_OPT_PERSISTENT, 1);
  4. $result = $client->some_method("parameter");
  5. /* The following calls will speed up due to keep-alive */
  6. $result = $client->some_other_method1("parameter");
  7. $result = $client->some_other_method2("parameter");
  8. $result = $client->some_other_method3("parameter");
  9. ?>

Custom hostname resolving

After Yar 2.1.0, if Yar runs on HTTP protocol, YAR_OPT_RESOLVE could be used to define custom hostname resolving.

  1. <?php
  2. $client = new Yar_Client("http://host/api/");
  3. $client->SetOpt(YAR_OPT_RESOLVE, array("host:80:127.0.0.1"));
  4. /* call goes to 127.0.0.1 */
  5. $result = $client->some_method("parameter");

Use http proxy

After Yar 2.2.1, if Yar runs on HTTP protocol, YAR_OPT_PROXY could be used to define http proxy , such as fidder or charles.

  1. <?php
  2. $client = new Yar_Client("http://host/api/");
  3. $client->SetOpt(YAR_OPT_PROXY,"127.0.0.1:8888"); //http proxy , Since 2.2.0
  4. /* call goes to 127.0.0.1 */
  5. $result = $client->some_method("parameter");

Protocols

Yar Header

Yar is no only designed for PHP only, all RPC request and response are transferred by binary data stream.

Key messages are exchanged by a struct called “Yar Header”:

  1. #ifdef PHP_WIN32
  2. #pragma pack(push)
  3. #pragma pack(1)
  4. #endif
  5. typedef struct _yar_header {
  6. uint32_t id; // transaction id
  7. uint16_t version; // protocol version
  8. uint32_t magic_num; // default is: 0x80DFEC60
  9. uint32_t reserved;
  10. unsigned char provider[32]; // reqeust from who
  11. unsigned char token[32]; // request token, used for authentication
  12. uint32_t body_len; // request body len
  13. }
  14. #ifndef PHP_WIN32
  15. __attribute__ ((packed))
  16. #endif
  17. yar_header_t;
  18. #ifdef PHP_WIN32
  19. #pragma pack(pop)
  20. #endif
  21. `

Packager Header

Yar also supports multi packager protocols, which is a char[8] before the header struct, to identicate which packager the body is packaged by.

Request

When a Client do an RPC request , the request is sent as an array(in PHP) like:

  1. <?php
  2. array(
  3. "i" => '', //transaction id
  4. "m" => '', //the method which being called
  5. "p" => array(), //parameters
  6. )

Server

When a server responses, the response is sent also as an array (in PHP) like:

  1. <?php
  2. array(
  3. "i" => '',
  4. "s" => '', //status
  5. "r" => '', //return value
  6. "o" => '', //output
  7. "e" => '', //error or exception
  8. )