2019独角兽企业重金招聘Python工程师标准>>>
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端示例:
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)串行:
$client = new Yar_Client("http://host/api/");
$result = $client->api("parameter);
?>
2)并行化调用
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
$service->handle();
直接在浏览器打开http://localhost/yar.php会显示API文档。
client端:yar_client.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的响应:
function callback($retval, $callinfo) {if ($callinfo == NULL) {//请求发送完毕,会运行到这里//做本地的逻辑return TRUE;}//RPC请求返回, callback会再次调用。返回值在$retval
}
实际项目里,Server端里为避免每次实例化当前类,可以写个父类:
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
Example #1 Yar Server示例
/* 假设这个页面的访问路径是: http://example.com/operator.php */
class Operator {
/**
* Add two operands
* @param interge
* @return interge
*/
public function add($a, $b) {
return $this->_add($a, $b);
}
/**
* Sub
*/
public function sub($a, $b) {
return $a - $b;
}
/**
* Mul
*/
public function mul($a, $b) {
return $a * $b;
}
/**
* Protected methods will not be exposed
* @param interge
* @return interge
*/
protected function _add($a, $b) {
return $a + $b;
}
}
$server = new Yar_Server(new Operator());
$server->handle();
?>
Example #2 通过浏览器访问(GET请求)
以上例程的输出类似于:
Example #3 Yar Client示例
$client = new yar_client("http://example.com/operator.php");
/* call directly */
var_dump($client->add(1, 2));
/* call via call */
var_dump($client->call("add", array(3, 2)));
/* __add can not be called */
var_dump($client->_add(1, 2));
?>
以上例程的输出类似于:
int(3)
int(5)
PHP Fatal error: Uncaught exception 'Yar_Server_Exception' with message 'call to api Operator::_add() failed' in *
Example #4 Yar Concurrent Client示例
function callback($ret, $callinfo) {
echo $callinfo['method'] , " result: ", $ret , "\n";
}
/* 注册一个异步调用 */
Yar_Concurrent_Client::call("http://example.com/operator.php", "add", array(1, 2), "callback");
Yar_Concurrent_Client::call("http://example.com/operator.php", "sub", array(2, 1), "callback");
Yar_Concurrent_Client::call("http://example.com/operator.php", "mul", array(2, 2), "callback");
/* 发送所有注册的调用, 等待返回, 返回后Yar会调用callback回掉函数 */
Yar_Concurrent_Client::loop();
?>
以上例程的输出类似于:
mul result: 4
sub result: 1
add result: 3