reprover/laravel-yar

Yar 的 Laravel 封装

1.3.2 2018-08-15 11:09 UTC

This package is auto-updated.

Last update: 2024-09-11 16:29:45 UTC


README

Yar

Yar 是鸟哥开发的轻量级 RPC 框架,纯 C 语言编写。前一阵自己找 RPC 的架子的时候,最终还是选定了 Yar。

为什么要用 RPC

  1. 很简单的例子,如果说我写一个项目,写完了之后写第二个项目时,需要重新开一个项目。
  2. 一个大项目,涉及到用户、论坛、问答、游戏等等特别大的框架,写在一个项目中太过庞大。
  3. 自己百度。。。

安装&配置

  1. 当前环境已安装 yar、msgpack 扩展:
pecl install msgpack
pecl install yar
  1. 在当前项目下执行:
composer require reprover/laravel-yar -vvv
  1. 配置
php artisan vendor:publish --tag="laravel-yar"

会复制三个配置文件到 config.php 目录下,分别为 yar.php:yar 运行时配置,yar-services.php:rpc 服务注册映射表,yar-map.php:mapName 与 接口参数对应表

  1. 修改中间件 在app/Http/Middleware/VerifyCsrfToken.php 中的 except 数组中加上
protected $except = [
    '/yar/*',
];

跳过 CSRF 验证

原理解释

同一个 Laravel 框架可以提供多个不同模块的服务,使用 URL 表示其模块地址和服务(后文讲),在不同服务中注册不同的方法去执行。客户端通过对应的地址执行方法,这个时候 yar 使用其自定义的规则去 curl 服务端,取回数据。在同机器上速度远远大于正常的 http 请求。说不清。。自己百度。。

使用

服务端

我们注册了一个路由用来代替 yar example 中的 server.php ,每次访问时会通过 Reprover/LaravelYar/Controllers/ 引导执行 app/Services 目录下的服务。客户端可以通过路由地址进行访问:

http://hostname/yar/{service}

在App/Services中的文件需 extends Reprover/LaravelYar/YarServices

示例代码

<?php
namespace App\Services;

use Reprover\LaravelYar\YarService;

class TestService extends YarService
{
    function test_method($parameters)
    {
        return ['parameter' => $parameters];
    }
}

这样就是一个服务,我们可以直接通过浏览器访问/yar/TestServices来查看服务注册了的方法,也可以直接使用客户端请求。

客户端

客户端则是我们封装了一个类用于同步/异步请求,并进行了接口的封装。

  1. 配置。要将所使用的服务与模块在 config/yar-services.php 中进行配置,默认有示例文件:
<?php
    return [
        'Example' => [
            'path' => 'http://resource.test/yar/', 'services' => [
            'ExampleService' => 'Example',
            'Example2Service' => 'Example2',
        ]
    ],
];

表示有一个 Example 模块(这个名字可以自定义的),path 则是对应的地址,注意 URL 后的 / 要加上。services 数组下分别表示此模块下的服务别名=>服务名。服务别名可以自定义,在当前服务中使用。对应的是服务方的服务名称。 2. 配置 map

<?php
return [
    'get_example' => [
        'module' => 'Example',
        'service' => 'ExampleService',
        'method' => 'getExample',
        'connect_timeout' => 1000,
        'read_timeout' => 5000,
    ]
];

get_example 是 apiName,其中定义的就是这个接口的参数。module 是模块,service 是服务,method 则是在 service 中定义的方法。使用方法必须先在 yar-services 中定义,目前没有做异常处理,如果调用到不存在的方法或服务会直接抛出。

  1. 使用 同步调用
  • 最简单:
<?php 
use Reprover/LaravelYar/Yar;

$ret = Yar::test_get([123]);
var_dump($ret);
  • 最标准:
<?php

$yarClient = new \Reprover\LaravelYar\Yar('test_get');
$ret = $yarClient->call([123]);

异步调用

  • 最简单:
<?php
\Reprover\LaravelYar\Yar::asyncCall("test_get",[123],function($ret, $callbackinfo){
    var_dump($ret);
});
\Reprover\LaravelYar\Yar::asyncCall("test_get",[456],function($ret, $callbackinfo){
    var_dump($ret);
});
\Reprover\LaravelYar\Yar::loop();
  • 最标准:
<?php
$yarClient = new \Reprover\LaravelYar\Yar('test_get', true);
$yarClient->setCallback(function($ret, $callbackinfo){
                            var_dump($ret);
                        });
$yarClient->call([789]);
$yarClient::loop();

使用上需要注意的问题

  1. curl 使用当前环境作为基准,也就是说,使用 Laradock 类似的环境,将 nginx 作为 docker 提供服务的,会出现 curl 找不到服务器的报错。
  2. 远程服务调用过程中,可能会出现其他人恶意访问的情况,注意添加 IP 白名单
  3. 鸟哥的扩展优点在于快,缺点呢个人感觉是使用上的 "优雅" 问题。但是这种 "优雅" 必然是以牺牲性能为代价的。在 Laravel 中,使用 Laravel 的方式去实现 Yar,我觉得应该是最标准的方式了。
  4. 其他比如 protocol 等慢慢添加。有问题欢迎 issue。