php7 yar扩展,php扩展之Yar使用

a87d8a8c6576a46fa3d9cb13e1b828eb.png

Yar 是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法.

有个业务场景,需要本地项目去调用一个服务层的相关方法实现相应的功能,一般情况,可以通过普通的http的方式进行请求即可,但是如果只是这个服务是内部使用,那么可以使用rpc的方式进行替代.好处自不必多说,基于tcp传输,支持并发结合在项目中使用。

首先介绍服务端:RpcServer.php

namespace appindexlogic;

/**

* rpc基类(服务端)

*/

class RpcServer

{

private static $signs = [

"sign1", //不同的来源Salt不同

"sign2",

];

// 验证签名

protected function checkSign($params,$sign)

{

if(empty($sign)){

return false;

}

ksort($params);

$signStr = "";

foreach($params as $key => $val)

{

if(empty($val) || $val == $sign) continue;

$signStr .= $key."=".$val."&";

}

$signStr = rtrim($signStr,"&");

foreach (self::$signs as $v){

if(md5($signStr.$v) === $sign){

return true;

}

}

}

// 处理结果

protected function response($status,$data)

{

$response = [

"status" => $status,

"message" => "", //状态码对应的信息(从配置文件中获取)

"data" => $data,

];

return $response;

}

}

服务端方法:

namespace appindexlogic;

class User extends RpcServer

{

// 用户扩展信息

public function userExt($ids)

{

// 1.验证签名

// 2.逻辑处理

// 3.结果返回

return $ids;

}

// 用户基础信息

public function userBase($ids)

{

return $ids;

}

}

客户端:RpcClient.php

namespace appindexlogic;

/**

* rpc基类(客户端)

*/

class RpcClient

{

private static $signs = [

"sign1", //不同来源

"sign2"

];

private $callBack;

private $callNum = 0;

/**

* 取得签名

* @param $params 接口调用时的参数

*/

protected function getSign($params,$type)

{

ksort($params);

$signStr = "";

foreach($params as $key => $val)

{

if(empty($val)) continue;

$signStr .= $key."=".$val."&";

}

$signStr = rtrim($signStr,"&");

return md5($signStr.self::$signs[$type]);

}

/**

* 调用服务端接口

* @param $server Api server

* @param $api 接口

* @param $params 参数

* @param $openSign 开启签名

* @param $callBack 回调

*/

public function call($server,$api,$params,$openSign=false,$callBack=null)

{

if($openSign){

$params["sign"] = $this->getSign($params);

}

if($callBack === null){

$client = new Yar_Client($server);

return call_user_func_array([$client,$api], $params);

}

$this->callNum ++;

$this->callBack = $callBack;

return Yar_Concurrent_Client::call($server,$api,$params,array($this, "ApiClientCallBack"));

}

/**

* 执行并发调用

*/

public function loop()

{

return Yar_Concurrent_Client::loop([$this,"callback1"],[$this,"error_callback"]);

}

/**

* 并发调用回调

* @param $retval

* @param $callinfo

*/

public function ApiClientCallBack($retval,$callinfo)

{

if($callinfo === null){

return $this->callBack($retval,$callinfo);

}

static $data = array();

$data[] = $retval; //并发

if(count($data) == $this->callNum){

$fn = $this->callBack;

return $this->$fn($data,$callinfo);

}

}

//

public function callback1($retval, $callinfo)

{

if ($callinfo == NULL) {

echo "现在, 所有的请求都发出去了, 还没有任何请求返回

";

} else {

echo "这是一个远程调用的返回, 调用的服务名是", $callinfo["method"],

". 调用的sequence是 " , $callinfo["sequence"] , "

";

var_dump($retval);

}

}

// 异常回调

public function error_callback($type, $error, $callinfo)

{

error_log(json_encode(func_get_args() ),3,"rpc.log" );

}

}

客户端调用:

namespace appindexlogic;

// 相关测试

class Test extends RpcClient

{

public function testRpc()

{

$api = "http://thinkphp.com/index/rpc/users";

// $this->call($api,"userExt",[1,2],false,"callback");

$this->call($api,"userBase",[3,4],false,"callback");

$this->call($api,"userBase",[5],false,"callback");

$this->loop();

return false;

// $client = new yar_client("http://thinkphp.com/index/rpc/user");

// $ret = $client->userInfo([1,2]);

// var_dump($ret);

}

// 回调数据

public function callback($data,$callinfo)

{

var_dump(func_get_args());die;

// static $a = [];

// $a[] = json_encode(func_get_args());

// print_r($a);

// error_log(json_encode(func_get_args() ),3,"rpc.log" );

}

}

即可实现简单的rpc调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值