yii2整合yar实现RPC

来源:互联网 发布:淘宝分销货源平台 编辑:程序博客网 时间:2024/05/20 01:44

近来用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

<?phpnamespace 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

<?phpnamespace 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

<?phpnamespace 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;

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

原创粉丝点击