abovesky/laravel-yar

Yar 的 Laravel 封装

v1.0.1 2021-08-06 11:45 UTC

This package is auto-updated.

Last update: 2024-09-06 18:29:37 UTC


README

安装&配置

  1. 当前环境已安装 yar 和 msgpack 扩展:
pecl install msgpack
pecl install yar
  1. 在当前项目下执行:
composer require abovesky/laravel-yar -vvv
  1. 配置
php artisan vendor:publish --provider="Abovesky\LaravelYar\ServiceProvider"

将复制三个配置文件到 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 中的 server.php,每次访问时会通过 Abovesky/LaravelYar/Controllers/ 引导执行 app/Services 目录下的服务。客户端可以通过路由地址进行访问:

http://hostname/yar/{service}

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

示例代码

<?php
namespace App\Services;

use Abovesky\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://example.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 Abovesky/LaravelYar/Yar;

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

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

异步调用

  • 最简单:
<?php
\Abovesky\LaravelYar\Yar::asyncCall("test_get",[123],function($ret, $callbackinfo){
    var_dump($ret);
});
\Abovesky\LaravelYar\Yar::asyncCall("test_get",[456],function($ret, $callbackinfo){
    var_dump($ret);
});
\Abovesky\LaravelYar\Yar::loop();
  • 最标准:
<?php
$yarClient = new \Abovesky\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。