yii2整合yar实现RPC

3 篇文章 0 订阅
2 篇文章 0 订阅

近来用YII2开发一个商城系统,里面用到有关RPC。考虑到YAR在这方面性能比较突出,就试着自己捣鼓一下。
总的来说,实现起来并不复杂,具体步骤如下。

准备工作

配置网站环境
安装yii2(高级版)
参考http://www.yiichina.com/doc/guide/2.0/start-installation
这里不再赘述。
配置 Nginx,设置两个测试域名。

 server_name  yii.test localhost;

RPC服务端

在 backend/controllers/ 下,新建文件 RpcController.php

<?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客户端

在 common/ 新建目录 rpc,在 common/rpc/新建文件 YarApi.php

<?php

namespace common\rpc;

/**
 * Yar rpc client
 *
 * @author 郭志强
 * @return void
 * @date: 2017-06-28
 *
 */
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://yii.test/rpc/index/', //服务器URL
            '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));
    }
}

美化URL

修改文件 backend/config/main.php

        'urlManager' => [
            'enablePrettyUrl' => true,  //美化url==ture
            'enableStrictParsing' => false,  //不启用严格解析
            'showScriptName' => false,   //隐藏index.php
            'rules' => [
                '<controller:rpc>/<action:\w+>/<rpctoken:.+>' => '<controller>/<action>',              
            ],
        ],

新建model 类

在目录 backend/models/,新建 Per.php

<?php
/**
 * $Author: Zhiqiang Guo
 * $Id: Per 
 * $date 2017/6/29
*/
namespace backend\models;

use Yii;
use yii\db;
use yii\base\Model;
use yii\db\ActiveRecord;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use common\models\LoginForm;
/**
 * 权限表的model类
 *
 * @category   Custom 
 * @package   Custom_Common
 * @author     name
 */
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;

    }

}

测试

在目录 backend/controllers/, 新建 TestController.php

<?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 "<pre>";
var_dump( $query);
echo "</pre>";
exit;
    }
}

运行 http://yii.test/test/index, 正确的话,会有数据输出。

注意事项

第一,要正确配置urlManager,配置不正确,是无法实现RPC的。
第二,关闭CSFT ,这是一个坑。关闭整个controller的CSFT方法是,在控制器内加上

   /**
     * 关闭csft
     * @var string
     * @access public
     */
    public $enableCsrfValidation = false;

希望本文能给需要的朋友带来一定帮助,再次感谢大家能花时间读完,如有什么问题或建议请回复。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值