Yar是什么
Yar是並行的RPC框架(Concurrent RPC framework),Laruence開發。
安裝
下載地址:http://pecl.php.net/package/yar
windows版本下載對應的擴展放到ext目錄並更新php.ini:
[yar]
extension=php_yar.dll
Linux版本下載擴展的源碼進行編譯,將編譯出來的so動態庫放到extensions目錄(例如/usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/)並更新php.ini:
[yar]
extension=/usr/local/php/lib/php/extensions/no-debug-non-zts-20151012/yar.so
如何使用
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();
?>
Yar為了方便開發, 把文檔和接口綁定到了一起, 對於上面的例子, 如果我們是簡單的GET請求這個接口地址的話, 我們就會看到如下的信息頁面:
Yar Server: API
+API::api($parameter, $option = 'foo')
Client端也很簡單,有2種:
1)串行:
<?php
$client = new Yar_Client("http://host/api/");
$result = $client->api("parameter);
?>
2)並行化調用
<?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
?>
這樣, 所有的請求會一次發出, 只要有任何一個請求完成, 回調函數”callback”就會被立即調用.
這里還有一個細節, Yar見縫插針的不會浪費任何時間, 在這些請求發送完成以后, Yar會調用一次callback, 和普通的請求返回回調不同, 這次的調用的$callinfo參數為空.
示例
server端:yar.php
<?php
class API {
/**
* the doc info will be generated automatically into service info page.
* @params
* @return
*/
public function test() {
sleep(1);
return 't';
}
public function test2() {
sleep(3);
return 'test2';
}
}
$service = new Yar_Server(new API());
$service->handle();
直接在瀏覽器打開http://localhost/yar.php會顯示API文檔。
client端:yar_client.php
<?php
//串行調用
//$client = new Yar_Client("http://localhost/yar.php");
//$client->test();
//$client->test2();
function callback($retval, $callinfo) {
//var_dump($retval);
error_log(time().':callinfo:'.json_encode($callinfo).PHP_EOL, 3, 't.log');
if ($callinfo == NULL) {
//做本地的邏輯
//return TRUE;
error_log(time().':'.'send req success'.PHP_EOL, 3, 't.log');
}else{
error_log(time().':'.$retval.PHP_EOL, 3, 't.log');
}
}
function callback2($retval, $callinfo) {
}
function error_callback($type, $error, $callinfo) {
error_log($error);
}
//並行調用:
//1、所有請求發送成功,Yar會調用一次callback,其中$callinfo為null
//2、每個請求執行完成,獲取到了結果,也會去調用callback,其中$callinfo不為null
$res = Yar_Concurrent_Client::call("http://localhost/yar.php", "test");
$res1 = Yar_Concurrent_Client::call("http://localhost/yar.php", "test2");
$res2 = Yar_Concurrent_Client::loop("callback", "error_callback"); //send
t.log:
1472832899:callinfo:null
1472832899:send req success
1472832900:callinfo:{"sequence":1,"uri":"http:\/\/localhost\/yar.php","method":"test"}
1472832900:t
1472832902:callinfo:{"sequence":2,"uri":"http:\/\/localhost\/yar.php","method":"test2"}
1472832902:test2
log驗證了yar的執行過程。那么,實際應用中,我們就可以先發送請求, 請求發送完畢,然后得到第一次回調($callinfo為null), 繼續做我們當前進程的工作; 等所有工作結束以后, 再交給Yar去獲取並行RPC的響應:
<?php
function callback($retval, $callinfo) {
if ($callinfo == NULL) {
//請求發送完畢,會運行到這里
//做本地的邏輯
return TRUE;
}
//RPC請求返回, callback會再次調用。返回值在$retval
}
實際項目里,Server端里為避免每次實例化當前類,可以寫個父類:
<?php
/**
*Yar控制器類
*/
class YarAction{
/**
* 架構函數
* @access public
*/
public function __construct() {
//判斷擴展是否存在
if(!extension_loaded('yar'))
die('yar not support');
//實例化Yar_Server
$server = new Yar_Server($this);
// 啟動server
$server->handle();
}
}
資料
1、文檔: http://www.laruence.com/2012/09/15/2779.html
2、擴展下載: http://pecl.php.net/package/yar/
3、github: https://github.com/laruence/yar
參考:
yar粗略使用記錄 - 軒脈刃 - 博客園
http://www.cnblogs.com/yjf512/p/3448474.html
