RPC 远程过程调用

Yar 是使用C语言扩展的一个RPC框架。

Yar是基于HTTP协议传输的。

Yar整个传输使用二进制流的形式传送

Yar的传输协议是Curl

Yar远程调用的实现原理

yar client 是通过 _call 这个魔术方法来实现远程调用的,在 Yar_Client 类里面 并没有任何方法,当我们再调用一个不存在的方法是就会自动调用 _call 这个方法。

Yar协议分析

yar_response_t 中的 retval 这是 返回的结果值。

Yar 实现一个简单的RPC

Server.php

client.php

目录

sign算法:

1、所有数据 按 k 倒序

2、通过k=$val&k2=$val2 拼接成字符串

3、通过sign=秘钥 使用 - 与上边的字符连接

4、通过md5 加密后 生成。

这个sign的算法 服务器、客户端都保持通用。

数据先进行加减密:

倘若数组中出现了 _enctype='r' 这样的值,则系统自动按照 content 进行解密处理$data=[

'email'=>'574482856@qq.com',

'title'=>'发送test邮件',

'email_body'=>'这是一封邮件 请查收'

];

//定义一个方法,通过调用方法,自动填充需要验证的值,

//这个值,一经填充,不能再次修改,这是要发送到服务器的数据。

//会自动添加sign 数据

$content=AESEncode(json_encode($data),true);

$http_url='172.28.81.111:8888/message';

$client=Yar_client($http_url);

$sendData=[

'content'=>$content,

'_enctype'=>'r'

];

$result=$client->sendMessage($sendData);

print_r($result);

这种方法的设计有一种问题,就是很不清楚调用这项服务需要传递的参数。综合考虑吧!

解密处理后,自动赋值给数组。数组中的值经过sign 计算到 sign  与 get 中传递的sign进行对比,倘若一致,则放行。否则阻止。

我们在yaf_client 的时候,能否通过抓包工具,抓到发送的数据? 需要做一个测试

=============================

思考:

如果进行加减密传递数组的形式,进行传递,那么 sign 是否通过 $_data 这样的方式传递,不使用_GET 进行传递了?

如果是这样,所有的接口中

=============================

对sign的判断,这是一定要判断的,传出中不需要传递 秘钥,只需要加密的时候,带上即可。

这个验证非常好,客户来源IP,如果不在这个IP范围内,则不能访问//验证IP

if (!in_array(Yii::$app->request->userIP, $this->ipArr)) {

return FALSE;

}

//有效时间

if ((time() - $param['time']) > $this->activeTime) {

return FALSE;

}

//验证密码

if ($param['password'] !== $this->password) {

return FALSE;

}

if (empty($param['class'])) {

return FALSE;

}

整个RPC框架的开发,不但需要考虑服务端如何部署开发,亦要开发响应客户端如何建立 ,如何应用。

一个yii2 框架开发结合yar 实现的RPC框架,看看实现步骤:

RPC服务端

新建文件 RpcController.php,在这里展示出了怎样进行加解密的处理,以及如何访问。

RPC服务端做了什么事情:

1、声明了RPC控制器类,并声明了重要的参数 ,如:加解密的秘钥、有效时间、以及关闭csrf 攻击关闭

2、提供index 方法,对外提供服务

3、auth() 权限验证,是否授权用户?

对密码、有效期、数据 进行了严格的判断

4、rpcDecode 方法 对传递字符进行解密处理

5、执行 yar_server 创建类,并执行handle() 方法对外提供服务

具体试下代码如下:<?php

namespace backend\controllers;

use Yii;

use common\controllers\CommonController;

use yii\web\Controller;

/**

* rpc controller

*/

class RpcController extends CommonController {

/**

* 关闭csft

* @var string

* @access public

*/

public $enableCsrfValidation = FALSE;

/**

* ip

* @var string

* @access private

*/

private $ipArr = ['127.0.0.1', '192.168.1.110'];

/**

* 密码

* @var string

* @access private

*/

private $password = 'Add25f37';

/**

* 有效时间   秒

* @var string

* @access private

*/

private $activeTime = 1440;

/**

* 暂无说明

*

* @author Zhiqiang Guo

* @return void

* @throws Exception

* @access public

*/

public function actionIndex() {

$request = Yii::$app->request;

//解密

$data = $this->rpcDecode($request->get('rpctoken'));

//权限认证

if (!$this->auth($data)) {

return;

}

try {

$server = new \Yar_Server(new $data['class']());

$server->handle();

} catch (Exception $e) {

return;

$e->getMessage();

}

//        return $this->render('index');

}

/**

* 权限认证

*

* @author Zhiqiang Guo

* @return void

* @throws Exception

* @access private

*/

private function auth($param) {

if (!$param) {

return FALSE;

}

//验证IP

if (!in_array(Yii::$app->request->userIP, $this->ipArr)) {

return FALSE;

}

//有效时间

if ((time() - $param['time']) > $this->activeTime) {

return FALSE;

}

//验证密码

if ($param['password'] !== $this->password) {

return FALSE;

}

if (empty($param['class'])) {

return FALSE;

}

return TRUE;

}

/**

* 解密

*

* @author Zhiqiang Guo

* @return void

* @throws Exception

* @access private

*/

private function rpcDecode($str) {

if ($str) {

return json_decode(base64_decode($str), TRUE);

}

return [];

}

}

RPC客户端

YarApi.php<?php

class YarApi {

/**

* 密码

* @var string

* @access private

*/

private $password = 'Add25f37';

/**

* 暂无说明

*

* @author Zhiqiang Guo

* @return void

* @throws Exception

* @access public

*/

public function api(array $condition) {

$defult = [

'url' => 'http://localhost/rpc/index/', //服务器URL

'class' => '', //class名称

];

$condition = array_merge($defult, $condition);

$data = [];

$data['time'] = time();

$data['password'] = $this->password;

$data['class'] = $condition['class'];

return new \Yar_Client("{$condition['url']}{$this->rpcEncode($data)}");

}

/**

* 加密

*

* @author Zhiqiang Guo

* @return void

* @throws Exception

* @access private

*/

private function rpcEncode(array $data) {

return base64_encode(json_encode($data));

}

}

运行测试<?php

namespace backend\controllers;

use Yii;

use common\controllers\CommonController;

use yii\web\Controller;

use common\rpc\YarApi;

/**

* 测试

*

* @author Zhiqiang Guo

* @date 2017-07-02

*/

class TestController extends CommonController {

/**

* No explanation

*

* @author Zhiqiang Guo

* @return void

* @throws Exception

* @access public

*/

public function actionIndex() {

$condition = ['class' => '\backend\models\Per'];

$yar = new YarApi();

$model = $yar->api($condition);

$query = $model->SelAll();

echo "

";

var_dump($query);

echo "

";

exit;

}

}

解释说明$condition = ['class' => '\backend\models\Per'];

Per 这是服务端创建的一个服务对象,里面提供了一个SelAll()的方法,对外提供服务。

代码如下:class Per extends ActiveRecord {

/**

* 暂无说明

*

* @author name

* @return void

* @throws Exception

* @access public

*/

public function rules() {

return [

];

}

/**

* 返回一个你要查询的表名

*

* @author name

* @return void

* @throws Exception

* @access public

*/

public static function tableName() {

//表名

return 'system_per';

}

/**

* 查询权限的所有数据

*

* @author name

* @return void

* @throws Exception

* @access public

*/

public function SelAll() {

$res = Per::find()->asArray()->All();

return $res;

}

}

这是一个成熟的RPC框架,整个项目基于swoole开发:

https://github.com/xcl3721/Dora-RPC

yar php使用,使用Yar 实现RPC框架相关推荐

  1. PHP 中流行的 rpc 框架有哪些

    目录 PHP 中流行的 rpc 框架有哪些 第1章 什么是rpc框架 1.1 什么是 RPC 框架 1.2 那什么是远程调用? 第2章 RPC与Socket有什么区别 第3章 RPC与REST有什么区 ...

  2. php 常用rpc框架,php的轻量级rpc框架yar

    php的轻量级rpc框架yar 目的:类方法的远程调用,也就是一个rpc请求. RPC本质上也是一个网络请求,既然是请求,对于效率来说,就需要考虑了.yar是基于http来做的. 使用场景:多个项目共 ...

  3. motan学习笔记 一 微博轻量级RPC框架Motan

    前言 motan学习笔记 一 微博轻量级RPC框架Motan motan学习笔记 二 motan架构分析 motan学习笔记 三 motan Demo 分析 motan学习笔记 四 motan Dem ...

  4. rpc介绍,和PHP常用的rpc框架

    什么是rpc框架 先回答第一个问题:什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 通常我们调用一个PHP中的方法,比如 ...

  5. 微博轻量级RPC框架Motan

    Motan 正式开源了,项目地址为https://github.com/weibocom/motan.微博技术团队希望未来能有更多优秀的开源人入驻,并进一步完善优化. 微博轻量级RPC框架Motan正 ...

  6. php中流行的rpc框架有哪些?

    什么是rpc框架 先回答第一个问题:什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 通常我们调用一个php中的方法,比如 ...

  7. rpc是什么?php中流行的rpc框架有哪些?

    什么是rpc框架 先回答第一个问题:什么是RPC框架?如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 通常我们调用一个php中的方法,比如这 ...

  8. 中间件 rpc是什么?php中流行的中间件rpc框架有哪些

    rpc是什么?php中流行的rpc框架有哪些. 更好的排版:https://www.zybuluo.com/phper/note/76641 什么是rpc框架 先回答第一个问题:什么是RPC框架? 如 ...

  9. [转]php中流行的rpc框架有哪些?

    什么是rpc框架 先回答第一个问题:什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote Procedure Call) 那什么是远程调用? 通常我们调用一个php中的方法,比如 ...

  10. RPC是什么?RPC与REST、Socket的区别?php中流行的rpc框架有哪些?

    RPC是什么?RPC与REST.Socket的区别?php中流行的RPC框架有哪些? 什么是RPC框架 先回答第一个问题:什么是RPC框架? 如果用一句话概括RPC就是:远程调用框架(Remote P ...

最新文章

  1. Week02-Java基本语法与类库
  2. 客户提的功能(需求),不能随口一说就当做,要分析其实质价值,多思考。
  3. C#获取文件夹下指定格式的所有文件
  4. 【Leetcode | 48】226. 翻转二叉树
  5. 找call的万能方法,一招通杀所有网络游戏【个人实践出来的】
  6. Mac下安装pthread扩展
  7. python 核心编程_【02】Python核心编程 (全)
  8. java管理分类编写_java029学生管理系统的编写
  9. k8s部署jar包_K8S部署SpringBoot应用_都超的博客-CSDN博客_k8s springboot
  10. MySQL 表分区功能详解
  11. ubuntu20.04版本下,ssh学习传输文件
  12. pygame详细安装教程
  13. launch参数JAVA_javafx主要方法launch(args)如何工作? - java
  14. java服务端–支付宝APP支付接口
  15. js增加透明css样式,如何配置透明发光的骚气 vscode
  16. TX2+TensorRT+DIGITS实现图像的识别、检测和分割---1---Jetson配置
  17. 2022年SCI期刊最新影响因子正式发布
  18. 视频文件格式转换怎么操作?如何进行视频文件格式转换?
  19. 字符串使用split()方法截取时的空字符串问题
  20. 智能语音将成下一代人机交互新入口

热门文章

  1. 2021不堪回首,2022满路荆棘,但依然乐观努力
  2. 关于电脑网速网占用问题(svchost.exe)(¥72)
  3. 管理之路:你的格局,决定你的结局
  4. Python爬虫 使用Selenium爬取腾讯招聘信息
  5. 机器人感知:因子图在SLAM中的应用(读书笔记)第一至三章
  6. Stratified Sampling(分层采样)
  7. ssh-keygen认证密钥
  8. 保护Android网络数据教程
  9. 华硕美版路由器RT-AC1200G+解决无线信号弱问题
  10. Logstash过滤器之Mutate过滤器详解