abovesky / laravel-yar
Yar 的 Laravel 封装
Requires
- php: >=7.1.0
- laravel/framework: ~5.5|~6.0|~7.0|~8.0
README
安装&配置
- 当前环境已安装 yar 和 msgpack 扩展:
pecl install msgpack pecl install yar
- 在当前项目下执行:
composer require abovesky/laravel-yar -vvv
- 配置
php artisan vendor:publish --provider="Abovesky\LaravelYar\ServiceProvider"
将复制三个配置文件到 config.php 目录下,分别为 yar.php:Yar 运行时配置,yar-services.php:RPC 服务注册映射表,yar-map.php:mapName 与 接口参数对应表
- 在 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
来查看服务注册了的方法,也可以直接使用客户端请求。
客户端
客户端则是一个用于同步/异步请求的类封装,并对接口进行了封装。
- 配置。要将所使用的服务与模块在 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 中定义,目前没有做异常处理,如果调用到不存在的方法或服务会直接抛出。
- 使用 同步调用
- 最简单:
<?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();
使用时需要注意的问题
- curl 使用当前环境作为基准,也就是说,使用 Laradock 类似的环境,将 nginx 作为 docker 提供服务的,会出现 curl 找不到服务器的报错。
- 远程服务调用过程中,可能会出现其他人恶意访问的情况,注意添加 IP 白名单
- 鸟哥的扩展优点在于快,缺点呢个人感觉是使用上的 "优雅" 问题。但是这种 "优雅" 必然是以牺牲性能为代价的。在 Laravel 中,使用 Laravel 的方式去实现 Yar,我觉得应该是最标准的方式了。
- 其他比如 protocol 等慢慢添加。有问题欢迎 issue。