php扩展之Yar使用
2020-04-07 00:00
435 查看
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调用
相关文章推荐
- Redis 创始人宣布 Redis 6.0.0 稳定版正式 GA
- PHP7的新特性和源码结构
- 一条SQL查询语句是如何执行的?
- PHP代码实现平衡二叉树详解
- shell脚本编程之expect
- 协程与Swoole框架的相关应用
- mysql误删数据快速恢复
- Go新手容易犯的三个致命错误,你中招了吗?
- 打造 Zap 开箱即用日志组件
- 这可能是搭建Zookeeper集群介绍最全的文章
- 八个字节的 UDP 如何传输数据
- Apache 和 Nginx 下的 URL 重写
- php多进程编程详解
- B/S架构和C/S架构
- PHP 注册错误和异常处理机制
- 提高mysql千万级数据SQL查询优化30条
- 分布式消息队列应用场景之异步处理、应用解耦、流量削锋和消息通讯理解分析
- MySQL5.7特性:JSON数据类型
- PHP 编写守护进程
- Redis中bitmap的妙用