什么是RPC
RPC,全称是Remote Procedure Call,远程服务调用,是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。简单一点来理解就是网络上的一个节点请求另一个节点提供的服务。
什么是YAF
Yaf,全称 Yet Another Framework,使用C语言编写,是一个以PHP扩展形式提供的PHP开发框架。相比于一般的PHP框架,它更快、更轻便,它提供了Bootstrap、路由、分发、视图、插件,是一个全功能的PHP框架。
YAF框架如何下载安装
什么是YAR
Yar,全称Yet Another RPC framework for PHP,?是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法。
YAR扩展如何安装
YAR文档
准备工作
使用上面的YAF框架安装教程部署2个一模一样的项目,并绑定域名a.myyaf.com做服务端,绑定域名b.myyaf.com做客户端。
服务端实现
0x01,新建application/library/servers/CalculatorServer.php
<?php
namespace Servers;
class CalculatorServer {
/**
* 加法
* @param $left
* @param $right
* @return mixed
*/
public function plus($left,$right) {
return $left + $right;
}
/**
* 减法
* @param $left
* @param $right
* @return mixed
*/
public function minus($left,$right){
return $left - $right;
}
/**
* 乘法
* @param $left
* @param $right
* @return mixed
*/
public function mul($left,$right){
return $left * $right;
}
/**
* 除法
* @param $left
* @param $right
* @return mixed
*/
public function div($left, $right){
return $left / $right;
}
}
0x02,新建application/controllers/Rpc.php
<?php
class RpcController extends \Yaf\Controller_Abstract {
public function calculatorAction() {
$server = new \Yar_Server(new \MyRpc\Servers\CalculatorServer());
$server->handle();
return false;
}
}
使用get方法请求链接,可以查看对应server的接口列表和注释。
客户端实现
0x01,调用远程服务
编辑application\controllers\Index.php
<?php
class IndexController extends \Yaf\Controller_Abstract {
public function indexAction() {
$client = new \Yar_Client('http://a.myyaf.com/rpc/calculator');
$left = 1;
$right = 2;
$result = $client->plus($left,$right);
echo "{$left} + {$right} = {$result}";
return false;
}
}
访问b.myyaf.com查看下效果
0x02,并行调用远程服务
编辑application\controllers\Index.php,新增loopAction、callBack、errorCallBack三个函数
<?php
class IndexController extends \Yaf\Controller_Abstract {
public function loopAction(){
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2]);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3]);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4]);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3]);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
return false;
}
public function callBack($retval, $callinfo){
echo '调用成功回调<hr/>';
}
public function errorCallBack($type, $error, $callinfo){
echo '调用失败回调<hr/>';
}
}
?访问b.myyaf.com/index/loop查看下效果
0x03,并行调用指定回调函数、错误回调函数
上面调用结果是5个调用成功回调,这个是因为\Yar_Concurrent_Client::call未设置回调函数,默认会使用\Yar_Concurrent_Client::loop的回调函数。可以分别指定每个\Yar_Concurrent_Client::call的回调函数、错误回调函数。
<?php
class IndexController extends \Yaf\Controller_Abstract {
# 并行调用
public function loopAction(){
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
return false;
}
public function callBack($retval, $callinfo){
echo '调用成功回调<hr/>';
}
public function errorCallBack($type, $error, $callinfo){
echo '调用失败回调<hr/>';
}
public function plusCallBack($retval, $callinfo){
echo "加法回调,结果:{$retval}<hr/>";
}
public function minusCallBack($retval, $callinfo){
echo "减法回调,结果:{$retval}<hr/>";
}
public function mulCallBack($retval, $callinfo){
echo "乘法回调,结果:{$retval}<hr/>";
}
public function divCallBack($retval, $callinfo){
echo "除法回调,结果:{$retval}<hr/>";
}
}
再次访问b.myyaf.com/index/loop查看下效果?
0x04,多次调用loop
如果在一次请求里面多次使用loop,后面的loop会携带上次loop的请求结果。
服务端编辑application/library/servers/CalculatorServer.php,新增square函数
<?php
namespace Servers;
class CalculatorServer {
/**
* 加法
* @param $left
* @param $right
* @return mixed
*/
public function plus($left,$right) {
return $left + $right;
}
/**
* 减法
* @param $left
* @param $right
* @return mixed
*/
public function minus($left,$right){
return $left - $right;
}
/**
* 乘法
* @param $left
* @param $right
* @return mixed
*/
public function mul($left,$right){
return $left * $right;
}
/**
* 除法
* @param $left
* @param $right
* @return mixed
*/
public function div($left, $right){
return $left / $right;
}
/**
* 平方
* @param $a
* @return float|int
*/
public function square($a){
return $a * $a;
}
}
?客户端编辑application\controllers\Index.php
<?php
class IndexController extends \Yaf\Controller_Abstract {
# 并行调用
public function loopAction(){
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','square',[6],[$this,'squareCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
return false;
}
public function callBack($retval, $callinfo){
echo '调用成功回调<hr/>';
}
public function errorCallBack($type, $error, $callinfo){
echo '调用失败回调<hr/>';
}
public function plusCallBack($retval, $callinfo){
echo "加法回调,结果:{$retval}<hr/>";
}
public function minusCallBack($retval, $callinfo){
echo "减法回调,结果:{$retval}<hr/>";
}
public function mulCallBack($retval, $callinfo){
echo "乘法回调,结果:{$retval}<hr/>";
}
public function divCallBack($retval, $callinfo){
echo "除法回调,结果:{$retval}<hr/>";
}
public function squareCallBack($retval, $callinfo){
echo "平方回调,结果:{$retval}<hr/>";
}
}
?可以在loop之前使用\Yar_Concurrent_Client::reset()清空上一次loop的结果
<?php
class IndexController extends \Yaf\Controller_Abstract {
# 并行调用
public function loopAction(){
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
Yar_Concurrent_Client::reset();
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','square',[6],[$this,'squareCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
return false;
}
public function callBack($retval, $callinfo){
echo '调用成功回调<hr/>';
}
public function errorCallBack($type, $error, $callinfo){
echo '调用失败回调<hr/>';
}
public function plusCallBack($retval, $callinfo){
echo "加法回调,结果:{$retval}<hr/>";
}
public function minusCallBack($retval, $callinfo){
echo "减法回调,结果:{$retval}<hr/>";
}
public function mulCallBack($retval, $callinfo){
echo "乘法回调,结果:{$retval}<hr/>";
}
public function divCallBack($retval, $callinfo){
echo "除法回调,结果:{$retval}<hr/>";
}
public function squareCallBack($retval, $callinfo){
echo "平方回调,结果:{$retval}<hr/>";
}
}
?0x05,运行时配置
yar的配置项包含以下内容:
yar.timeout,处理超时,默认5000ms
yar.connect_timeout,连接超时,默认1000ms
yar.packager,打包方式,有php、json、msgpack三种方式,默认是php,当使用--enable-msgpack构建时默认“msgpack”
yar.debug,默认关闭
yar.content_type,默认是application/octet-stream
yar.allow_persistent,持续连接,默认关闭
接下来,我们来测试下处理超时的情况。
服务端编辑application/library/servers/CalculatorServer.php,修改plus函数
<?php
namespace Servers;
class CalculatorServer {
/**
* 加法
* @param $left
* @param $right
* @return mixed
*/
public function plus($left,$right) {
sleep(5);
return $left + $right;
}
/**
* 减法
* @param $left
* @param $right
* @return mixed
*/
public function minus($left,$right){
return $left - $right;
}
/**
* 乘法
* @param $left
* @param $right
* @return mixed
*/
public function mul($left,$right){
return $left * $right;
}
/**
* 除法
* @param $left
* @param $right
* @return mixed
*/
public function div($left, $right){
return $left / $right;
}
/**
* 平方
* @param $a
* @return float|int
*/
public function square($a){
return $a * $a;
}
}
客户端编辑application\controllers\Index.php,修改indexAction函数
<?php
class IndexController extends \Yaf\Controller_Abstract {
public function indexAction() {
$client = new \Yar_Client('http://a.myyaf.com/rpc/calculator');
$client->setOpt(YAR_OPT_CONNECT_TIMEOUT,1);
$client->setOpt(YAR_OPT_TIMEOUT,1);
$left = 1;
$right = 2;
$result = $client->plus($left,$right);
echo "{$left} + {$right} = {$result}";
return false;
}
}
?并行调用也可以设置配置。
<?php
class IndexController extends \Yaf\Controller_Abstract {
# 并行调用
public function loopAction(){
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','plus',[1,2],[$this,'plusCallBack'],[$this,'plusErrorCallBack'],[YAR_OPT_TIMEOUT=>1,YAR_OPT_CONNECT_TIMEOUT=>1]);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','minus',[5,3],[$this,'minusCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','mul',[3,4],[$this,'mulCallBack']);
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','div',[9,3],[$this,'divCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
Yar_Concurrent_Client::reset();
\Yar_Concurrent_Client::call('http://a.myyaf.com/rpc/calculator','square',[6],[$this,'squareCallBack']);
Yar_Concurrent_Client::loop([$this,'callback'], [$this,'errorCallBack']);
return false;
}
public function callBack($retval, $callinfo){
echo '调用成功回调<hr/>';
}
public function errorCallBack($type, $error, $callinfo){
echo '调用失败回调<hr/>';
}
public function plusCallBack($retval, $callinfo){
echo "加法回调,结果:{$retval}<hr/>";
}
public function plusErrorCallBack($type, $error, $callinfo){
echo "加法错误回调:{$error}<hr/>";
}
public function minusCallBack($retval, $callinfo){
echo "减法回调,结果:{$retval}<hr/>";
}
public function mulCallBack($retval, $callinfo){
echo "乘法回调,结果:{$retval}<hr/>";
}
public function divCallBack($retval, $callinfo){
echo "除法回调,结果:{$retval}<hr/>";
}
public function squareCallBack($retval, $callinfo){
echo "平方回调,结果:{$retval}<hr/>";
}
}
也可以使用ini_set()设置
ini_set('yar.timeout',1000);
ini_set('yar.connect_timeout',1000);
也可以直接修改php.ini设置
yar.timeout = 1000
yar.connect_time = 1000
|