Yar 是一个轻量级, 高效的RPC框架, 它提供了一种简单方法来让PHP项目之间可以互相远程调用对方的本地方法. 并且Yar也提供了并行调用的能力. 可以支持同时调用多个远程服务的方法。
有个业务场景,需要本地项目去调用一个服务层的相关方法实现相应的功能,一般情况,可以通过普通的http的方式进行请求即可,但是如果只是这个服务是内部使用,那么可以使用rpc的方式进行替代.好处自不必多说,基于tcp传输,支持并发结合在项目中使用。
首先介绍服务端:RpcServer.php
服务端方法:
<?php namespace app\index\logic; class User extends RpcServer { // 用户扩展信息 public function userExt($ids) { // 1.验证签名 // 2.逻辑处理 // 3.结果返回 return $ids; } // 用户基础信息 public function userBase($ids) { return $ids; } }
客户端:RpcClient.php
<?php namespace app\index\logic; /** * 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 "现在, 所有的请求都发出去了, 还没有任何请求返回\n"; } else { echo "这是一个远程调用的返回, 调用的服务名是", $callinfo["method"], ". 调用的sequence是 " , $callinfo["sequence"] , "\n"; var_dump($retval); } } // 异常回调 public function error_callback($type, $error, $callinfo) { error_log(json_encode(func_get_args() ),3,'rpc.log' ); } }
客户端调用:
<?php namespace app\index\logic; // 相关测试 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调用
扫码二维码 获取免费视频学习资料
- 本文固定链接: http://phpxs.com/post/7222/
- 转载请注明:转载必须在正文中标注并保留原文链接
- 扫码: 扫上方二维码获取免费视频资料
查 看2022高级编程视频教程免费获取