正在显示
34 个修改的文件
包含
0 行增加
和
2706 行删除
README.md
已删除
100755 → 0
| 1 | -## 简介 | ||
| 2 | -AukeySwrpc是一个基于swoole开发的高性能rpc包,AukeySwrpc提供了注册发现,链路追踪,中间件等等功能,可以很容易集成到第三方框架,如laravel,yii等等。 | ||
| 3 | - | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -## 功能 | ||
| 7 | - | ||
| 8 | -- 支持多进程模式或协程模式 | ||
| 9 | -- 支持同步,异步调用 | ||
| 10 | -- 支持自定义中间件 | ||
| 11 | -- 支持服务端按类提供对外服务 | ||
| 12 | -- 支持链路追踪 | ||
| 13 | -- 支持注册服务发现 | ||
| 14 | -- 支持客户端负载均衡,包含随机,权重两种模式 | ||
| 15 | -- 支持自定义日志,包协议,序列化方式等等 | ||
| 16 | - | ||
| 17 | - | ||
| 18 | - | ||
| 19 | -## 安装 | ||
| 20 | - | ||
| 21 | -```bash | ||
| 22 | -php composer.phar require wuzhc/swprc ~1.0 -vvv | ||
| 23 | -``` | ||
| 24 | - | ||
| 25 | - | ||
| 26 | - | ||
| 27 | -## 快速体验 | ||
| 28 | - | ||
| 29 | -假设我们User和School两个模块,为了获得用户学校名称,我们需要在User模块发起rpc请求调用School模块的服务。 | ||
| 30 | - | ||
| 31 | -### School模块 | ||
| 32 | - | ||
| 33 | -```php | ||
| 34 | -<?php | ||
| 35 | -use AukeySwrpc\LogicService; | ||
| 36 | -class SchoolService extends LogicService | ||
| 37 | -{ | ||
| 38 | - public function getUserSchool($userID) { | ||
| 39 | - $name = $userID == 123 ? '火星' : '水星'; | ||
| 40 | - return $name.'学校'; | ||
| 41 | - } | ||
| 42 | -} | ||
| 43 | -``` | ||
| 44 | - | ||
| 45 | -School模块将作为rpc服务端,对外提供服务,启动如下: | ||
| 46 | - | ||
| 47 | -```php | ||
| 48 | -<?php | ||
| 49 | -namespace AukeySwrpcTests; | ||
| 50 | -use AukeySwrpc\Server; | ||
| 51 | - | ||
| 52 | -$basePath = dirname(dirname(__FILE__)); | ||
| 53 | -require_once $basePath . "/vendor/autoload.php"; | ||
| 54 | - | ||
| 55 | -$options = [ | ||
| 56 | - 'enable_coroutine' => true, | ||
| 57 | - 'pid_file' => __DIR__ . '/AukeySwrpc.pid', | ||
| 58 | -]; | ||
| 59 | -$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); | ||
| 60 | -$server->addService(\AukeySwrpcTests\services\SchoolService::class); | ||
| 61 | -$server->start(); | ||
| 62 | -``` | ||
| 63 | - | ||
| 64 | -将SchoolService添加到server,server会自动检索类中所有可用的public方法。 | ||
| 65 | - | ||
| 66 | - | ||
| 67 | - | ||
| 68 | - | ||
| 69 | - | ||
| 70 | -### User模块 | ||
| 71 | - | ||
| 72 | -User模块作为客户端,调用School模块服务如下 | ||
| 73 | - | ||
| 74 | -```php | ||
| 75 | -<?php | ||
| 76 | -namespace AukeySwrpcTests; | ||
| 77 | -use AukeySwrpc\Request; | ||
| 78 | -use AukeySwrpc\LogicService; | ||
| 79 | -use AukeySwrpc\Client; | ||
| 80 | - | ||
| 81 | -class UserService extends LogicService | ||
| 82 | -{ | ||
| 83 | - public function getUserSchoolName() | ||
| 84 | - { | ||
| 85 | - $userID = 123; | ||
| 86 | - $module = 'School_Module'; //请求目标模块名称,需要和服务端定义的一致 | ||
| 87 | - $client = Client::create($module, '127.0.0.1', 9501); | ||
| 88 | - return $client->send(Request::create('\AukeySwrpcTests\services\SchoolService_getUserSchool', [$userID])); | ||
| 89 | - } | ||
| 90 | -} | ||
| 91 | - | ||
| 92 | -//调用 | ||
| 93 | -echo UserService::factory()->getUserSchoolName(); | ||
| 94 | -``` | ||
| 95 | -注意: | ||
| 96 | -- Request.method 为服务类命名 + 下划线 + 方法名,例如上面的`\AukeySwrpcTests\services\SchoolService_getUserSchool`,如果服务类有命名空间,记得一定要带上命名空间 | ||
| 97 | - | ||
| 98 | - | ||
| 99 | - | ||
| 100 | -## 多进程和协程模式 | ||
| 101 | - | ||
| 102 | -多进程或协程模式需要和swoole配置一致,具体参考swoole配置 | ||
| 103 | - | ||
| 104 | -### 多进程模式 | ||
| 105 | - | ||
| 106 | -创建10进程来处理请求 | ||
| 107 | - | ||
| 108 | -```php | ||
| 109 | -$options = [ | ||
| 110 | - 'worker_num' => 10 | ||
| 111 | - 'pid_file' => __DIR__ . '/AukeySwrpc.pid', | ||
| 112 | -]; | ||
| 113 | -$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); | ||
| 114 | -``` | ||
| 115 | - | ||
| 116 | -### 协程模式 | ||
| 117 | - | ||
| 118 | -目前AukeySwrpc协程模式是运行在单进程的 | ||
| 119 | - | ||
| 120 | -```php | ||
| 121 | -$options = [ | ||
| 122 | - 'enable_coroutine' => true, | ||
| 123 | - 'pid_file' => __DIR__ . '/AukeySwrpc.pid', | ||
| 124 | -]; | ||
| 125 | -$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); | ||
| 126 | -``` | ||
| 127 | - | ||
| 128 | - | ||
| 129 | - | ||
| 130 | -## 同步调用和异步调用 | ||
| 131 | - | ||
| 132 | -在客户端发起同步调用,客户端会一直等待服务端返回结果 | ||
| 133 | - | ||
| 134 | -```php | ||
| 135 | -$client = \AukeySwrpc\Client::create($module, '127.0.0.1', 9501); | ||
| 136 | -return $client->send(SyncRequest::create('SchoolService_getUserSchool', [$userID])); | ||
| 137 | -``` | ||
| 138 | - | ||
| 139 | -在客户端发起异步调用,客户端会立马得到响应结果,请求将被swoole的task进程处理 | ||
| 140 | - | ||
| 141 | -```php | ||
| 142 | -$client = \AukeySwrpc\Client::create($module, '127.0.0.1', 9501); | ||
| 143 | -return $client->send(AsyncRequest::create('SchoolService_getUserSchool', [$userID])); | ||
| 144 | -``` | ||
| 145 | - | ||
| 146 | - | ||
| 147 | - | ||
| 148 | -## 自定义中间件 | ||
| 149 | - | ||
| 150 | -中间件允许程序可以对请求进行前置操作和后置操作,底层使用了责任链设计模式,所以为了执行下一个中间件,必须返回`$next($request)`,如果想提前返回,则返回结果必须是`AukeySwrpc\Response`类型 | ||
| 151 | - | ||
| 152 | -```php | ||
| 153 | -//中间件除了用匿名函数定义,还可以用实现AukeySwrpc\Middlewares\MiddlewareInterface接口的类 | ||
| 154 | -$middleware = function (\AukeySwrpc\Request $request, Closure $next) { | ||
| 155 | - $start = microtime(true); //前置操作,记录请求开始时间 | ||
| 156 | - $result = $next($request); | ||
| 157 | - echo '耗时:'.(microtime(true) - $start).PHP_EOL; //后置操作,记录请求结束时间,从而计算请求耗时 | ||
| 158 | - return $result; //继续下个中间件的处理 | ||
| 159 | -}; | ||
| 160 | -$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); | ||
| 161 | -$server->addService(SchoolService::class); | ||
| 162 | -$server->addMiddleware($middleware); //添加中间件 | ||
| 163 | -$server->start(); | ||
| 164 | -``` | ||
| 165 | -如果要提前中止中间件,可以提前在匿名函数或类方法中返回\AukeySwrpc\Response对象,如下 | ||
| 166 | -```php | ||
| 167 | -$middleware = function (\AukeySwrpc\Request $request, Closure $next) { | ||
| 168 | - if (empty($request->getParams())) { | ||
| 169 | - return \AukeySwrpc\Response::error('参数不能为空'); //提前返回,必须是Response类型 | ||
| 170 | - } | ||
| 171 | - return $next($request); | ||
| 172 | -}; | ||
| 173 | -``` | ||
| 174 | - | ||
| 175 | - | ||
| 176 | - | ||
| 177 | -## 服务端按类提供对外服务 | ||
| 178 | - | ||
| 179 | -从上面的例子中,我们把SchoolService整个类添加的server中,这样server就能对外提供SchoolService类所有public方法的功能。 | ||
| 180 | - | ||
| 181 | -```php | ||
| 182 | -$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); | ||
| 183 | -$server->addService(SchoolService::class); //提供SchoolService所有public方法功能 | ||
| 184 | -$server->addService(AreaService::class); //提供AreaService所有public方法功能 | ||
| 185 | -$server->start(); | ||
| 186 | -``` | ||
| 187 | -客户端使用参考上面的快速体验 | ||
| 188 | - | ||
| 189 | - | ||
| 190 | - | ||
| 191 | -## 注册服务发现 | ||
| 192 | - | ||
| 193 | -如果服务端启动的时候有设置注册中心,则启动成功会自动向注册中心注册服务端地址。目前AukeySwrpc提供了`Consul`作为注册中心,使用如下 | ||
| 194 | - | ||
| 195 | -```php | ||
| 196 | -$server = new Server('School_Module', '127.0.0.1', 9501, 1, $options); | ||
| 197 | -$server->addRegister(new Consul()); | ||
| 198 | -$server->addService(SchoolService::class); | ||
| 199 | -$server->start(); | ||
| 200 | -``` | ||
| 201 | - | ||
| 202 | -如上,使用Consul作为服务的注册中心,通过`http://127.0.0.1:8500`可以查看注册信息,如果想用etcd等其他注册中心,只要实现`AukeySwrpc\Middlewares\RegisterInterface`接口即可,然后在通过`$server->addRegister()`添加到server | ||
| 203 | - | ||
| 204 | - | ||
| 205 | - | ||
| 206 | - | ||
| 207 | - | ||
| 208 | - | ||
| 209 | - | ||
| 210 | - | ||
| 211 | - | ||
| 212 | -## 客户端负载均衡 | ||
| 213 | - | ||
| 214 | -如果服务端启动多个节点,例如School模块启动3个节点,并且注册到了注册中心,那么我们可以从注册中心获取所有服务端节点信息,然后做一些策略处理。 | ||
| 215 | - | ||
| 216 | -```php | ||
| 217 | -$register = new Consul(); | ||
| 218 | -$client = \AukeySwrpc\Client::createBalancer('School_Module', $register, \AukeySwrpc\Client::STRATEGY_WEIGHT); | ||
| 219 | -$result = $client->send(Request::create('SchoolService_getUserSchool', [$userID]); | ||
| 220 | -``` | ||
| 221 | - | ||
| 222 | -目前AukeySwrpc提供两种简单策略模式,`\AukeySwrpc\Client::STRATEGY_WEIGHT权重模式`,`\AukeySwrpc\Client::STRATEGY_RANDOM`随机模式 | ||
| 223 | - | ||
| 224 | - | ||
| 225 | - | ||
| 226 | -## 链路追踪 | ||
| 227 | - | ||
| 228 | -当我们的服务非常多并且需要互相调用时候,如果其中某个调用失败,会导致我们得不到我们想要的结果,而要调试出是哪个环节出了问题也比较麻烦,可能你需要登录每台机器看下有没有错误日志,或者看返回的错误信息是哪个服务提供的。链路追踪记录了整个调用链过程,如果某个环节出错,我们可以快速从调用链得到调用中断地方。 | ||
| 229 | - | ||
| 230 | -```php | ||
| 231 | -class UserService extends LogicService | ||
| 232 | -{ | ||
| 233 | - public function getUserSchoolName() | ||
| 234 | - { | ||
| 235 | - $userID = 123; | ||
| 236 | - $module = 'School_Module'; //请求目标模块名称,需要和服务端定义的一致 | ||
| 237 | - $client = Client::create($module, '127.0.0.1', 9501); | ||
| 238 | - return $client->send(Request::create('SchoolService_getUserSchool', [$userID], $this->getTracerContext(__FUNCTION__))); //getTracerContext()用于提供追踪上下文 | ||
| 239 | - } | ||
| 240 | -} | ||
| 241 | - | ||
| 242 | -$users = UserService::factory() | ||
| 243 | - ->setModule('User_Module') //当前模块,用于调用链的起点 | ||
| 244 | - ->setTracerUrl('http://127.0.0.1:9411/api/v2/spans') //zipkin链路追踪地址 | ||
| 245 | - ->getUserSchoolName(); | ||
| 246 | -``` | ||
| 247 | - | ||
| 248 | - | ||
| 249 | - | ||
| 250 | -如图,User_Module调用Class_Module,Class_Module又去调用School_Module | ||
| 251 | - | ||
| 252 | - | ||
| 253 | - | ||
| 254 | -每个调用还记录响应结果 | ||
| 255 | - | ||
| 256 | - | ||
| 257 | - | ||
| 258 | - | ||
| 259 | -## 自定义日志处理器 | ||
| 260 | -默认使用`Monolog/Logger`作为日志处理器,日志信息会输出到控制台。可根据自己需求覆盖默认处理器,只要日志类 | ||
| 261 | -实现`Psr\Log\LoggerInterface`即可 | ||
| 262 | -```php | ||
| 263 | -use AukeySwrpc\Server; | ||
| 264 | -use Monolog\Handler\StreamHandler; | ||
| 265 | -use Monolog\Logger; | ||
| 266 | - | ||
| 267 | -$logger = new Logger('AukeySwrpc'); | ||
| 268 | -$logger->pushHandler(new StreamHandler(fopen('xxxx.log','w+'), Logger::DEBUG)); | ||
| 269 | - | ||
| 270 | -$server = new Server('127.0.0.1', 9501, ['enable_coroutine'=>true]); | ||
| 271 | -$server->addService(UserService::class); | ||
| 272 | -$server->addLogger($logger); //覆盖默认日志处理器 | ||
| 273 | -$server->start(); | ||
| 274 | -``` | ||
| 275 | - | ||
| 276 | - | ||
| 277 | - | ||
| 278 | -## 序列化方式 | ||
| 279 | - | ||
| 280 | -默认使用固定头+包体来解决**tcp粘包**问题,默认配置为`'package_length_type' => 'N'`,`'package_body_offset' => 4` | ||
| 281 | -默认序列化数据会使用`serialize()`,如果swoole版本在4.5以上的自动使用swoole_substr_unserialize(),可以实现的类来覆盖默认配置,只要实现`src/Packer/PackerInterface`即可,注意服务端和客户端需要使用一样的协议,否则解析不了。 | ||
| 282 | - | ||
| 283 | -```php | ||
| 284 | -use AukeySwrpc\Server; | ||
| 285 | - | ||
| 286 | -$packer = new \AukeySwrpc\Packer\SerializeLengthPacker(); | ||
| 287 | -$server = new Server('127.0.0.1', 9501, ['enable_coroutine'=>true]); | ||
| 288 | -$server->addService(UserService::class); | ||
| 289 | -$server->addPacker($packer); //覆盖默认值 | ||
| 290 | -``` | ||
| 291 | - | ||
| 292 | - | ||
| 293 | - | ||
| 294 | -## 安全证书配置 | ||
| 295 | - | ||
| 296 | -参考:<https://wiki.swoole.com/#/server/setting?id=ssl_cert_file> | ||
| 297 | - | ||
| 298 | -### 服务端 | ||
| 299 | - | ||
| 300 | -```php | ||
| 301 | -$options = [ | ||
| 302 | - 'ssl_cert_file' => __DIR__.'/config/ssl.crt', | ||
| 303 | - 'ssl_key_file' => __DIR__.'/config/ssl.key', | ||
| 304 | - 'pid_file' => __DIR__ . '/AukeySwrpc.pid', | ||
| 305 | -]; | ||
| 306 | -$server = new Server('School_Module', '127.0.0.1', 9501, $options, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL); | ||
| 307 | -$server->addService(SchoolService::class); | ||
| 308 | -$server->start(); | ||
| 309 | -``` | ||
| 310 | - | ||
| 311 | -注意: | ||
| 312 | - | ||
| 313 | -- 文件必须为 `PEM` 格式,不支持 `DER` 格式,可使用 `openssl` 工具进行转换 | ||
| 314 | - | ||
| 315 | - | ||
| 316 | - | ||
| 317 | -## 测试 | ||
| 318 | - | ||
| 319 | -使用phpuint实现的简单测试案例,配置文件`phpunit.xml`,根据你的服务器配置ip地址 | ||
| 320 | - | ||
| 321 | -```bash | ||
| 322 | -php phpunit.phar tests --debug | ||
| 323 | -``` | ||
| 324 | - | ||
| 325 | - | ||
| 326 | - | ||
| 327 | -### phpunit 测试报告 | ||
| 328 | - | ||
| 329 | -``` | ||
| 330 | -Client (AukeySwrpcTests\Client) | ||
| 331 | - [x] Client connect | ||
| 332 | - [x] Client sync request | ||
| 333 | - [x] Client async request | ||
| 334 | - | ||
| 335 | -Packer (AukeySwrpcTests\Packer) | ||
| 336 | - [x] Serialize length pack | ||
| 337 | - [x] Serialize lenght unpack | ||
| 338 | - [x] Serialize eof pack | ||
| 339 | - [x] Serialize eof unpack | ||
| 340 | - | ||
| 341 | -Server (AukeySwrpcTests\Server) | ||
| 342 | - [x] Server register to consul | ||
| 343 | - [x] Server unregister from consul | ||
| 344 | - [x] Server add service | ||
| 345 | - [x] Server add middleware | ||
| 346 | -``` |
src/AukeySwrpcProvider.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | -use Illuminate\Support\ServiceProvider; | ||
| 6 | - | ||
| 7 | -class AukeySwrpcProvider extends ServiceProvider | ||
| 8 | -{ | ||
| 9 | - public function boot() | ||
| 10 | - { | ||
| 11 | - $this->loadMigrationsFrom(__DIR__ . '/database/migrations'); | ||
| 12 | - if ($this->app->runningInConsole()) { | ||
| 13 | - $this->commands([ | ||
| 14 | - \AukeyDataCenter\Commands\CreateBaseCode::class, | ||
| 15 | - \AukeyDataCenter\Commands\SheinReturnOrderCom::class, | ||
| 16 | - \AukeyDataCenter\Commands\SheinProductCom::class, | ||
| 17 | - \AukeyDataCenter\Commands\SheinBrandCom::class, | ||
| 18 | - ]); | ||
| 19 | - } | ||
| 20 | - } | ||
| 21 | - | ||
| 22 | - public function register() | ||
| 23 | - { | ||
| 24 | - $provides = [ | ||
| 25 | - 'AukeySwrpc\Http\RouteServiceProvider', | ||
| 26 | - ]; | ||
| 27 | - foreach ($provides as $provider) { | ||
| 28 | - $this->app->register($provider); | ||
| 29 | - } | ||
| 30 | - } | ||
| 31 | -} |
src/Client.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Swoole\Client as SwClient; | ||
| 7 | -use AukeySwrpc\Exceptions\RpcException; | ||
| 8 | -use AukeySwrpc\Packer\PackerInterface; | ||
| 9 | -use AukeySwrpc\Packer\SerializeLengthPacker; | ||
| 10 | -use AukeySwrpc\Register\RegisterInterface; | ||
| 11 | -use AukeySwrpc\Register\Service; | ||
| 12 | -use AukeySwrpc\Request\Request; | ||
| 13 | - | ||
| 14 | -/** | ||
| 15 | - * Class Client | ||
| 16 | - * | ||
| 17 | - * @package AukeySwrpc | ||
| 18 | - * @author pengjch 202439 11:36:25 | ||
| 19 | - */ | ||
| 20 | -class Client | ||
| 21 | -{ | ||
| 22 | - protected $services = []; | ||
| 23 | - protected $connects = []; | ||
| 24 | - | ||
| 25 | - | ||
| 26 | - const STRATEGY_RANDOM = 1; | ||
| 27 | - const STRATEGY_WEIGHT = 2; | ||
| 28 | - | ||
| 29 | - protected $mode; | ||
| 30 | - protected $timeout = 3; | ||
| 31 | - protected array $options; | ||
| 32 | - protected string $module; | ||
| 33 | - protected int $strategy; | ||
| 34 | - protected ?RegisterInterface $register = null; | ||
| 35 | - protected ?PackerInterface $packer = null; | ||
| 36 | - | ||
| 37 | - protected array $defaultOptions | ||
| 38 | - = [ | ||
| 39 | - 'open_length_check' => true, | ||
| 40 | - 'package_length_type' => 'N', | ||
| 41 | - 'package_length_offset' => 0, //第N个字节是包长度的值 | ||
| 42 | - 'package_body_offset' => 4, //第几个字节开始计算长度 | ||
| 43 | - 'package_max_length' => 81920, //协议最大长度 | ||
| 44 | - ]; | ||
| 45 | - | ||
| 46 | - /** | ||
| 47 | - * Client constructor. | ||
| 48 | - * | ||
| 49 | - * @param string $module | ||
| 50 | - * @param array $services | ||
| 51 | - * @param int $mode | ||
| 52 | - * @param int $timeout | ||
| 53 | - * @param array $options | ||
| 54 | - */ | ||
| 55 | - public function __construct(string $module, array $services, $mode = SWOOLE_SOCK_TCP, $timeout = 3, $options = []) | ||
| 56 | - { | ||
| 57 | - $this->module = $module; | ||
| 58 | - $this->services = $services; | ||
| 59 | - $this->mode = $mode; | ||
| 60 | - $this->timeout = $timeout; | ||
| 61 | - if (empty($options)) { | ||
| 62 | - $options = $this->defaultOptions; | ||
| 63 | - } | ||
| 64 | - $this->options = $options; | ||
| 65 | - | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - /** | ||
| 69 | - * @param string $module | ||
| 70 | - * @param string $host | ||
| 71 | - * @param int $port | ||
| 72 | - * @param int $mode | ||
| 73 | - * @param array $options | ||
| 74 | - * @return Client | ||
| 75 | - * @author pengjch 2024313 18:31:17 | ||
| 76 | - */ | ||
| 77 | - public static function create( | ||
| 78 | - string $module, | ||
| 79 | - string $host, | ||
| 80 | - int $port, | ||
| 81 | - $mode = SWOOLE_SOCK_TCP, | ||
| 82 | - $timeout = 3, | ||
| 83 | - $options = [] | ||
| 84 | - ): Client { | ||
| 85 | - $service = Service::build($host, $port, 1); | ||
| 86 | - return new static($module, [$service], $mode, $timeout, $options); | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - /** | ||
| 90 | - * @param string $module | ||
| 91 | - * @param RegisterInterface $register | ||
| 92 | - * @param int $strategy | ||
| 93 | - * @param int $mode | ||
| 94 | - * @param int $timeout | ||
| 95 | - * @param array $options | ||
| 96 | - * @return Client | ||
| 97 | - * @author pengjch 2024313 18:31:22 | ||
| 98 | - */ | ||
| 99 | - public static function createBalancer( | ||
| 100 | - string $module, | ||
| 101 | - RegisterInterface $register, | ||
| 102 | - $strategy = self::STRATEGY_RANDOM, | ||
| 103 | - $mode = SWOOLE_SOCK_TCP, | ||
| 104 | - $timeout = 3, | ||
| 105 | - $options = [] | ||
| 106 | - ): Client { | ||
| 107 | - $client = new static($module, [], $mode, $timeout, $options); | ||
| 108 | - $client->strategy = $strategy; | ||
| 109 | - $client->addRegister($register); | ||
| 110 | - return $client; | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - /** | ||
| 114 | - * @param RegisterInterface $register | ||
| 115 | - * @return $this | ||
| 116 | - * @author pengjch 2024313 18:27:20 | ||
| 117 | - */ | ||
| 118 | - public function addRegister(RegisterInterface $register): Client | ||
| 119 | - { | ||
| 120 | - $this->register = $register; | ||
| 121 | - $this->services = $this->register->getServices($this->module); | ||
| 122 | - return $this; | ||
| 123 | - } | ||
| 124 | - | ||
| 125 | - /** | ||
| 126 | - * @param PackerInterface $packer | ||
| 127 | - * @return $this | ||
| 128 | - * @author pengjch 2024313 18:27:24 | ||
| 129 | - */ | ||
| 130 | - public function addPacker(PackerInterface $packer): Client | ||
| 131 | - { | ||
| 132 | - $this->packer = $packer; | ||
| 133 | - return $this; | ||
| 134 | - } | ||
| 135 | - | ||
| 136 | - /** | ||
| 137 | - * @return SwClient | ||
| 138 | - * @throws RpcException | ||
| 139 | - * @author pengjch 2024313 18:23:37 | ||
| 140 | - */ | ||
| 141 | - public function connect(): SwClient | ||
| 142 | - { | ||
| 143 | - $n = count($this->services); | ||
| 144 | - if ($n == 0) { | ||
| 145 | - throw new RpcException('No services available'); | ||
| 146 | - } | ||
| 147 | - | ||
| 148 | - /** @var Service $service */ | ||
| 149 | - if ($n == 1) { //单个服务节点 | ||
| 150 | - $service = $this->services[0]; | ||
| 151 | - $key = $service->getHost() . '_' . $service->getPort(); | ||
| 152 | - } else { //多个服务节点 | ||
| 153 | - $key = $this->getConnectKey(); | ||
| 154 | - } | ||
| 155 | - | ||
| 156 | - if (isset($this->connects[$key]) && $this->connects[$key]->isConnected()) { | ||
| 157 | - return $this->connects[$key]; | ||
| 158 | - } | ||
| 159 | - $client = new SwClient($this->mode ?: SWOOLE_SOCK_TCP); | ||
| 160 | - if (!$client->connect($service->getHost(), $service->getPort(), $this->timeout ?? 3)) { | ||
| 161 | - throw new RpcException("connect failed. Error: {$client->errCode}"); | ||
| 162 | - } | ||
| 163 | - $client->set($this->options); | ||
| 164 | - $this->connects[$key] = $client; | ||
| 165 | - return $this->connects[$key]; | ||
| 166 | - } | ||
| 167 | - | ||
| 168 | - /** | ||
| 169 | - * 发送请求 | ||
| 170 | - * | ||
| 171 | - * @param Request $request | ||
| 172 | - * @return mixed | ||
| 173 | - * @throws RpcException | ||
| 174 | - * @author pengjch 202439 13:35:25 | ||
| 175 | - */ | ||
| 176 | - public function send(Request $request) | ||
| 177 | - { | ||
| 178 | - /** @var \Swoole\Client $conn */ | ||
| 179 | - $conn = $this->connect(); | ||
| 180 | - | ||
| 181 | - if (!$this->packer) { | ||
| 182 | - $this->packer = new SerializeLengthPacker([ | ||
| 183 | - 'package_length_type' => $options['package_length_type'] ?? 'N', | ||
| 184 | - 'package_body_offset' => $options['package_body_offset'] ?? 4, | ||
| 185 | - ]); | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | - $request->setModule($this->module); | ||
| 189 | - $conn->send($this->packer->pack($request)); | ||
| 190 | - | ||
| 191 | - /** @var Response $response */ | ||
| 192 | - $response = @unserialize($conn->recv()); | ||
| 193 | - if (!($response instanceof Response)) { | ||
| 194 | - throw new RpcException('The server return type is not a AukeySwrpc\Response'); | ||
| 195 | - } | ||
| 196 | - if ($response->code == Response::RES_ERROR) { | ||
| 197 | - throw new RpcException($response->msg); | ||
| 198 | - } | ||
| 199 | - | ||
| 200 | - return $response->data['result'] ?? null; | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - /** | ||
| 204 | - * @return string | ||
| 205 | - * @author pengjch 2024313 18:20:38 | ||
| 206 | - */ | ||
| 207 | - public function getConnectKey(): string | ||
| 208 | - { | ||
| 209 | - /** @var Service $service */ | ||
| 210 | - if ($this->strategy == self::STRATEGY_RANDOM) { | ||
| 211 | - $service = array_rand($this->services); | ||
| 212 | - return $service->getHost() . '_' . $service->getPort(); | ||
| 213 | - } else { | ||
| 214 | - /** @var Service $service */ | ||
| 215 | - foreach ($this->services as $service) { | ||
| 216 | - $totalWeight += $service->getWeight(); | ||
| 217 | - $sort[] = $service->getWeight(); | ||
| 218 | - $serviceArr[] = $service->toArray(); | ||
| 219 | - } | ||
| 220 | - | ||
| 221 | - array_multisort($serviceArr, SORT_DESC, $sort); | ||
| 222 | - | ||
| 223 | - $start = 0; | ||
| 224 | - $rand = rand(1, $totalWeight); | ||
| 225 | - foreach ($serviceArr as $service) { | ||
| 226 | - if ($start + $service['weight'] >= $rand) { | ||
| 227 | - return $service['host'] . '_' . $service['port']; | ||
| 228 | - } | ||
| 229 | - $start = $start + $service['weight']; | ||
| 230 | - } | ||
| 231 | - } | ||
| 232 | - } | ||
| 233 | - | ||
| 234 | - /** | ||
| 235 | - * 关闭客户端连接 | ||
| 236 | - * | ||
| 237 | - * @return mixed | ||
| 238 | - * @author pengjch 2024310 9:16:46 | ||
| 239 | - */ | ||
| 240 | - public function close() | ||
| 241 | - { | ||
| 242 | - foreach ($this->connects as $connect) { | ||
| 243 | - $connect->close(true); | ||
| 244 | - } | ||
| 245 | - } | ||
| 246 | - | ||
| 247 | - /** | ||
| 248 | - * 刷新节点服务信息 | ||
| 249 | - * 客户端使用长连接的情况下,需要起一个定时器来定时更新节点服务信息 | ||
| 250 | - * | ||
| 251 | - * @author pengjch 2024313 18:24:23 | ||
| 252 | - */ | ||
| 253 | - public function refreshServices() | ||
| 254 | - { | ||
| 255 | - if ($this->register) { | ||
| 256 | - $this->services = $this->register->getServices($this->module); | ||
| 257 | - $this->connects = []; | ||
| 258 | - } | ||
| 259 | - } | ||
| 260 | -} |
src/Commands/TestCom.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Commands; | ||
| 4 | - | ||
| 5 | -use AukeyCommon\Http\Orm\By\SheinOrderOrm; | ||
| 6 | -use AukeyCommon\Http\Orm\By\SheinStoreInfoOrm; | ||
| 7 | -use AukeyCommon\Http\Service\RabbitMq\RabbitMqDelayedSingleton; | ||
| 8 | -use AukeyDataCenter\Http\Orm\Shein\SheinBrandOrm; | ||
| 9 | -use AukeyDataCenter\Http\Orm\Shein\SheinProductItemOrm; | ||
| 10 | -use AukeyDataCenter\Http\Service\DataTimeService; | ||
| 11 | -use AukeyDataCenter\Http\Service\Shein\Request\RequestClient; | ||
| 12 | -use AukeyDataCenter\Http\Service\Shein\RouteMethod\OpenApiRouteMethod; | ||
| 13 | -use AukeyDataCenter\Http\Service\Shein\RoutePath\OpenApiRoutePath; | ||
| 14 | -use Illuminate\Console\Command; | ||
| 15 | - | ||
| 16 | -/** | ||
| 17 | - * SheinBrandCom.php | ||
| 18 | - * @Date 2024/03/12 22:23 | ||
| 19 | - * @author pengjch | ||
| 20 | - */ | ||
| 21 | -class TestCom extends Command | ||
| 22 | -{ | ||
| 23 | - /** | ||
| 24 | - * The name and signature of the console command. | ||
| 25 | - * | ||
| 26 | - * @var string | ||
| 27 | - */ | ||
| 28 | - protected $signature = 'swrpc:test'; | ||
| 29 | - | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * Create a new command instance. | ||
| 33 | - * | ||
| 34 | - * @return void | ||
| 35 | - */ | ||
| 36 | - public function __construct() | ||
| 37 | - { | ||
| 38 | - print_r(111);exit(); | ||
| 39 | - parent::__construct(); | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - /** | ||
| 43 | - * Execute the console command. | ||
| 44 | - * @throws \ErrorException | ||
| 45 | - */ | ||
| 46 | - public function handle() | ||
| 47 | - { | ||
| 48 | - $this->syncAllProduct(); | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - public function syncAllProduct() | ||
| 52 | - { | ||
| 53 | - $allAccounts = SheinStoreInfoOrm::query()->get(); | ||
| 54 | - if($allAccounts->isEmpty()){ | ||
| 55 | - return false; | ||
| 56 | - } | ||
| 57 | - $languageMap = [ | ||
| 58 | - 'US' => 'en', | ||
| 59 | - 'FR' => 'fr', | ||
| 60 | - 'ES' => 'es', | ||
| 61 | - 'DE' => 'de', | ||
| 62 | - 'TH' => 'th', | ||
| 63 | - 'BR' => 'pt-br', | ||
| 64 | - ]; | ||
| 65 | - foreach ($allAccounts as $account){ | ||
| 66 | - $this->error('account_name:'.$account->account_name.', account_id:'.$account->account_id.' 开始同步......'); | ||
| 67 | - $params = [ | ||
| 68 | - 'path' => OpenApiRoutePath::GOODS_QUERY_BRAND_LIST, | ||
| 69 | - 'method' => OpenApiRouteMethod::$routeMethod[OpenApiRoutePath::GOODS_QUERY_BRAND_LIST], | ||
| 70 | - 'openKeyId' => $account->open_key_id, | ||
| 71 | - 'secretKey' => $account->secretKey, | ||
| 72 | - 'queryParams' => [], | ||
| 73 | - 'headers' => [ | ||
| 74 | - 'language' => $languageMap[$account->site] ?? 'en', | ||
| 75 | - ], | ||
| 76 | - ]; | ||
| 77 | - $body = di(RequestClient::class)->sendRequest( | ||
| 78 | - $params['path'], | ||
| 79 | - $params['method'], | ||
| 80 | - $params['openKeyId'], | ||
| 81 | - $params['secretKey'], | ||
| 82 | - $params['queryParams'], | ||
| 83 | - $params['headers'] | ||
| 84 | - ); | ||
| 85 | - if(isset($body['error'])){ | ||
| 86 | - $this->error('错误信息:'.json_encode($body['error'])); | ||
| 87 | - continue; | ||
| 88 | - } | ||
| 89 | - if(!$body['info']['data']){ | ||
| 90 | - continue; | ||
| 91 | - } | ||
| 92 | - $data = $body['info']['data']; | ||
| 93 | - if(!is_array($data) || !$data){ | ||
| 94 | - continue; | ||
| 95 | - } | ||
| 96 | - foreach ($data as $datum){ | ||
| 97 | - $setAttr = [ | ||
| 98 | - 'account_id' => $account['account_id'], | ||
| 99 | - 'account_name' => $account['account_name'], | ||
| 100 | - 'account_site' => $account['site'], | ||
| 101 | - 'dept_id' => $account['dept_id'], | ||
| 102 | - 'dept_name' => $account['dept_name'], | ||
| 103 | - 'brand_code' => $datum['brand_code'], | ||
| 104 | - 'brand_name' => $datum['brand_name'], | ||
| 105 | - ]; | ||
| 106 | - $findAttr = [ | ||
| 107 | - 'account_id' => $account['account_id'], | ||
| 108 | - 'account_name' => $account['account_name'], | ||
| 109 | - 'account_site' => $account['site'], | ||
| 110 | - 'dept_id' => $account['dept_id'], | ||
| 111 | - 'dept_name' => $account['dept_name'], | ||
| 112 | - 'brand_code' => $datum['brand_code'], | ||
| 113 | - ]; | ||
| 114 | - db_util()->saveModel(new SheinBrandOrm(),$setAttr,$findAttr); | ||
| 115 | - $this->info('品牌编号:'.$datum['brand_code'].' - '.$datum['brand_name'].'同步完成.........'); | ||
| 116 | - } | ||
| 117 | - } | ||
| 118 | - $this->info('品牌同步完成.........'); | ||
| 119 | - } | ||
| 120 | -} |
src/Event.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | -trait Event | ||
| 6 | -{ | ||
| 7 | - public function OnWorkerStart(\Swoole\Server $server, int $workerId) | ||
| 8 | - { | ||
| 9 | - } | ||
| 10 | - | ||
| 11 | - public function onStart(\Swoole\Server $server) | ||
| 12 | - { | ||
| 13 | - } | ||
| 14 | - | ||
| 15 | - public function onShutdown(\Swoole\Server $server) | ||
| 16 | - { | ||
| 17 | - | ||
| 18 | - } | ||
| 19 | -} |
src/Exceptions/RequestException.php
已删除
100755 → 0
src/Exceptions/RpcException.php
已删除
100755 → 0
src/Exceptions/TypeException.php
已删除
100755 → 0
src/Http/RouteServiceProvider.php
已删除
100644 → 0
| 1 | -<?php | ||
| 2 | -namespace AukeySwrpc\Http; | ||
| 3 | - | ||
| 4 | -use Illuminate\Support\Facades\Route; | ||
| 5 | -use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; | ||
| 6 | - | ||
| 7 | -class RouteServiceProvider extends ServiceProvider{ | ||
| 8 | - public function boot(){ | ||
| 9 | - parent::boot(); | ||
| 10 | - } | ||
| 11 | - | ||
| 12 | - public function map(){ | ||
| 13 | - $this->mapWebRoutes(); | ||
| 14 | - | ||
| 15 | - $this->mapApiRoutes(); | ||
| 16 | - } | ||
| 17 | - | ||
| 18 | - /** | ||
| 19 | - * web路由设置 | ||
| 20 | - */ | ||
| 21 | - protected function mapWebRoutes(){ | ||
| 22 | - Route::middleware('web') | ||
| 23 | - ->namespace('AukeySwrpc\Http\Controllers') | ||
| 24 | - ->group(__DIR__ . '/Controllers/routes.php'); | ||
| 25 | - } | ||
| 26 | - | ||
| 27 | - /** | ||
| 28 | - * api路由设置 | ||
| 29 | - */ | ||
| 30 | - protected function mapApiRoutes(){ | ||
| 31 | - Route::prefix('api') | ||
| 32 | - ->middleware('api') | ||
| 33 | - ->namespace('AukeySwrpc\Http\Controllers') | ||
| 34 | - ->group(__DIR__ . '/Controllers/routes.php'); | ||
| 35 | - } | ||
| 36 | -} |
src/LogicService.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Tracer\TracerContext; | ||
| 7 | -use Zipkin\Endpoint; | ||
| 8 | -use Zipkin\Reporters\Http; | ||
| 9 | -use Zipkin\Samplers\BinarySampler; | ||
| 10 | -use Zipkin\TracingBuilder; | ||
| 11 | - | ||
| 12 | -/** | ||
| 13 | - * Class LogicService | ||
| 14 | - * | ||
| 15 | - * @package AukeySwrpc | ||
| 16 | - * @author pengjch 2024311 11:10:18 | ||
| 17 | - */ | ||
| 18 | -class LogicService | ||
| 19 | -{ | ||
| 20 | - protected $params; | ||
| 21 | - protected $module; | ||
| 22 | - protected $tracerUrl; | ||
| 23 | - protected $tracerContext; | ||
| 24 | - protected $clients = []; | ||
| 25 | - | ||
| 26 | - /** | ||
| 27 | - * @return static | ||
| 28 | - * @author pengjch 2024311 11:4:5 | ||
| 29 | - */ | ||
| 30 | - public static function factory() | ||
| 31 | - { | ||
| 32 | - return new static(); | ||
| 33 | - } | ||
| 34 | - | ||
| 35 | - /** | ||
| 36 | - * 初始化链路追踪器 | ||
| 37 | - * | ||
| 38 | - * @param $func | ||
| 39 | - * @author pengjch 2024311 11:3:36 | ||
| 40 | - */ | ||
| 41 | - public function initTracer($func) | ||
| 42 | - { | ||
| 43 | - $reporterUrl = $this->tracerUrl ?: 'http://127.0.0.1:9411/api/v2/spans'; | ||
| 44 | - $endpoint = Endpoint::create($this->module); | ||
| 45 | - $reporter = new Http(['endpoint_url' => $reporterUrl]); | ||
| 46 | - $sampler = BinarySampler::createAsAlwaysSample(); | ||
| 47 | - $tracing = TracingBuilder::create() | ||
| 48 | - ->havingLocalEndpoint($endpoint) | ||
| 49 | - ->havingSampler($sampler) | ||
| 50 | - ->havingReporter($reporter) | ||
| 51 | - ->build(); | ||
| 52 | - $tracer = $tracing->getTracer(); | ||
| 53 | - $span = $tracer->newTrace(); | ||
| 54 | - $span->setName($func); | ||
| 55 | - $span->start(); | ||
| 56 | - $span->finish(); | ||
| 57 | - $tracer->flush(); | ||
| 58 | - | ||
| 59 | - $ctx = $span->getContext(); | ||
| 60 | - if ($this->tracerContext) { | ||
| 61 | - $this->tracerContext->setTraceID($ctx->getTraceId()); | ||
| 62 | - $this->tracerContext->setParentID($ctx->getSpanId()); | ||
| 63 | - $this->tracerContext->setReporterUrl($reporterUrl); | ||
| 64 | - } else { | ||
| 65 | - $this->tracerContext = TracerContext::create($ctx->getTraceId(), $ctx->getSpanId(), $reporterUrl); | ||
| 66 | - } | ||
| 67 | - } | ||
| 68 | - | ||
| 69 | - /** | ||
| 70 | - * @param $context | ||
| 71 | - * @return $this | ||
| 72 | - * @author pengjch 2024311 11:18:43 | ||
| 73 | - */ | ||
| 74 | - public function setTracerContext($context) | ||
| 75 | - { | ||
| 76 | - $this->tracerContext = $context; | ||
| 77 | - return $this; | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | - /** | ||
| 81 | - * @param $func | ||
| 82 | - * @return null | ||
| 83 | - * @author pengjch 2024311 11:4:1 | ||
| 84 | - */ | ||
| 85 | - public function getTracerContext($func) | ||
| 86 | - { | ||
| 87 | - if (empty($this->tracerUrl)) { | ||
| 88 | - return null; | ||
| 89 | - } | ||
| 90 | - if (empty($this->tracerContext)) { | ||
| 91 | - $this->initTracer($func); | ||
| 92 | - } | ||
| 93 | - return $this->tracerContext; | ||
| 94 | - } | ||
| 95 | - | ||
| 96 | - /** | ||
| 97 | - * @param array $params | ||
| 98 | - * @return $this | ||
| 99 | - * @author pengjch 2024311 11:15:47 | ||
| 100 | - */ | ||
| 101 | - public function setParams(array $params) | ||
| 102 | - { | ||
| 103 | - $this->params = $params; | ||
| 104 | - return $this; | ||
| 105 | - } | ||
| 106 | - | ||
| 107 | - /** | ||
| 108 | - * @param string $url | ||
| 109 | - * @return static $this | ||
| 110 | - * @author pengjch 2024311 11:15:35 | ||
| 111 | - */ | ||
| 112 | - public function setTracerUrl(string $url) | ||
| 113 | - { | ||
| 114 | - $this->tracerUrl = $url; | ||
| 115 | - return $this; | ||
| 116 | - } | ||
| 117 | - | ||
| 118 | - /** | ||
| 119 | - * @param string $name | ||
| 120 | - * @return $this | ||
| 121 | - * @author pengjch 2024311 11:59:4 | ||
| 122 | - */ | ||
| 123 | - public function setModule(string $name) | ||
| 124 | - { | ||
| 125 | - $this->module = $name; | ||
| 126 | - return $this; | ||
| 127 | - } | ||
| 128 | -} |
src/Middlewares/MiddlewareInterface.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Middlewares; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Closure; | ||
| 7 | -use AukeySwrpc\Request\Request; | ||
| 8 | -use AukeySwrpc\Response; | ||
| 9 | - | ||
| 10 | -/** | ||
| 11 | - * Interface MiddlewareInterface | ||
| 12 | - * | ||
| 13 | - * @package AukeySwrpc\Middlewares | ||
| 14 | - * @author pengjch 202439 11:37:39 | ||
| 15 | - */ | ||
| 16 | -interface MiddlewareInterface | ||
| 17 | -{ | ||
| 18 | - function handle(Request $request, Closure $next): Response; | ||
| 19 | -} |
src/Middlewares/TraceMiddleware.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Middlewares; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Closure; | ||
| 7 | -use AukeySwrpc\Request\Request; | ||
| 8 | -use AukeySwrpc\Response; | ||
| 9 | -use Zipkin\Endpoint; | ||
| 10 | -use Zipkin\Propagation\TraceContext; | ||
| 11 | -use Zipkin\Reporters\Http; | ||
| 12 | -use Zipkin\Samplers\BinarySampler; | ||
| 13 | -use Zipkin\TracingBuilder; | ||
| 14 | - | ||
| 15 | -/** | ||
| 16 | - * 链路追踪中间件 | ||
| 17 | - * Class TraceMiddleware | ||
| 18 | - * | ||
| 19 | - * @package AukeySwrpc\Middlewares | ||
| 20 | - * @author pengjch 2024310 16:41:6 | ||
| 21 | - */ | ||
| 22 | -class TraceMiddleware implements MiddlewareInterface | ||
| 23 | -{ | ||
| 24 | - function handle(Request $request, Closure $next): Response | ||
| 25 | - { | ||
| 26 | - $context = $request->getTraceContext(); | ||
| 27 | - if (!$context) { | ||
| 28 | - return $next($request); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - $traceContext = TraceContext::create($context->getTraceID(), $context->getParentID(), null, true); | ||
| 32 | - $endpoint = Endpoint::create($request->getModule()); | ||
| 33 | - $reporter = new Http(['endpoint_url' => $context->getReporterUrl()]); | ||
| 34 | - $sampler = BinarySampler::createAsAlwaysSample(); | ||
| 35 | - $tracing = TracingBuilder::create() | ||
| 36 | - ->havingLocalEndpoint($endpoint) | ||
| 37 | - ->havingSampler($sampler) | ||
| 38 | - ->havingReporter($reporter) | ||
| 39 | - ->build(); | ||
| 40 | - | ||
| 41 | - $tracer = $tracing->getTracer(); | ||
| 42 | - $span = $tracer->newChild($traceContext); | ||
| 43 | - $span->setName($request->getMethod()); | ||
| 44 | - $span->start(); | ||
| 45 | - $span->tag('请求参数', serialize($request->getParams())); | ||
| 46 | - $request->setTraceContext($span->getContext()->getTraceId(), $span->getContext() | ||
| 47 | - ->getSpanId(), $context->getReporterUrl()); | ||
| 48 | - | ||
| 49 | - $start = microtime(true); | ||
| 50 | - $result = $next($request); | ||
| 51 | - $end = microtime(true); | ||
| 52 | - | ||
| 53 | - $span->tag('响应状态码code', $result->code); | ||
| 54 | - $span->tag('响应提示语msg', $result->msg); | ||
| 55 | - $span->tag('响应耗时', $end - $start); | ||
| 56 | - $span->finish(); | ||
| 57 | - $tracer->flush(); | ||
| 58 | - | ||
| 59 | - return $result; | ||
| 60 | - } | ||
| 61 | -} |
src/Packer/PackerInterface.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Packer; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Request\Request; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * Interface PackerInterface | ||
| 10 | - * | ||
| 11 | - * @package AukeySwrpc\Packer | ||
| 12 | - * @author pengjch 202439 11:37:10 | ||
| 13 | - */ | ||
| 14 | -interface PackerInterface | ||
| 15 | -{ | ||
| 16 | - function pack(Request $data):string; | ||
| 17 | - function unpack(string $data); | ||
| 18 | -} |
src/Packer/SerializeEofPacker.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Packer; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Request\Request; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * Class SerializeEofPacker | ||
| 10 | - * | ||
| 11 | - * @package AukeySwrpc\Packer | ||
| 12 | - * @author pengjch 202439 11:37:17 | ||
| 13 | - */ | ||
| 14 | -class SerializeEofPacker implements PackerInterface | ||
| 15 | -{ | ||
| 16 | - /** | ||
| 17 | - * @var string | ||
| 18 | - */ | ||
| 19 | - protected $eof; | ||
| 20 | - | ||
| 21 | - public function __construct(array $options = []) | ||
| 22 | - { | ||
| 23 | - $this->eof = $options['settings']['package_eof'] ?? "\r\n"; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public function pack(Request $data): string | ||
| 27 | - { | ||
| 28 | - return serialize($data); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - public function unpack(string $data) | ||
| 32 | - { | ||
| 33 | - return unserialize($data); | ||
| 34 | - } | ||
| 35 | -} |
src/Packer/SerializeLengthPacker.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Packer; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Request\Request; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * Class SerializeLengthPacker | ||
| 10 | - * | ||
| 11 | - * @package AukeySwrpc\Packer | ||
| 12 | - * @author pengjch 202439 11:37:27 | ||
| 13 | - */ | ||
| 14 | -class SerializeLengthPacker implements PackerInterface | ||
| 15 | -{ | ||
| 16 | - /** | ||
| 17 | - * @var string | ||
| 18 | - */ | ||
| 19 | - protected $type; | ||
| 20 | - | ||
| 21 | - /** | ||
| 22 | - * @var int | ||
| 23 | - */ | ||
| 24 | - protected $length; | ||
| 25 | - | ||
| 26 | - protected $defaultOptions | ||
| 27 | - = [ | ||
| 28 | - 'package_length_type' => 'N', | ||
| 29 | - 'package_body_offset' => 4, | ||
| 30 | - ]; | ||
| 31 | - | ||
| 32 | - public function __construct(array $options = []) | ||
| 33 | - { | ||
| 34 | - $options = array_merge($this->defaultOptions, $options['settings'] ?? []); | ||
| 35 | - | ||
| 36 | - $this->type = $options['package_length_type']; | ||
| 37 | - $this->length = $options['package_body_offset']; | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - public function pack(Request $data): string | ||
| 41 | - { | ||
| 42 | - $data = serialize($data); | ||
| 43 | - return pack($this->type, strlen($data)) . $data; | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | - public function unpack(string $data) | ||
| 47 | - { | ||
| 48 | - $package = unpack('N', $data); | ||
| 49 | - $len = $package[1]; | ||
| 50 | - | ||
| 51 | - //合并unserialize和substr,以减少内存拷贝 https://wenda.swoole.com/detail/107587 | ||
| 52 | - if (function_exists('swoole_substr_unserialize')) { | ||
| 53 | - return swoole_substr_unserialize($data, $this->length, $len); | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - $data = substr($data, $this->length, $len); | ||
| 57 | - return unserialize($data); | ||
| 58 | - } | ||
| 59 | -} |
src/Register/Consul.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Register; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use SensioLabs\Consul\ServiceFactory; | ||
| 7 | -use SensioLabs\Consul\Services\Agent; | ||
| 8 | -use SensioLabs\Consul\Services\AgentInterface as AgentInterfaceAlias; | ||
| 9 | -use SensioLabs\Consul\Services\Catalog; | ||
| 10 | -use SensioLabs\Consul\Services\CatalogInterface; | ||
| 11 | -use SensioLabs\Consul\Services\Health; | ||
| 12 | -use AukeySwrpc\Exceptions\RpcException; | ||
| 13 | - | ||
| 14 | -class Consul implements RegisterInterface | ||
| 15 | -{ | ||
| 16 | - protected $sf; | ||
| 17 | - protected array $options; | ||
| 18 | - protected array $serviceCache | ||
| 19 | - = [ | ||
| 20 | - 'ttl' => 10, | ||
| 21 | - 'services' => [], | ||
| 22 | - 'lastUpdateTime' => 0, | ||
| 23 | - ]; | ||
| 24 | - | ||
| 25 | - public function __construct($uri = 'http://127.0.0.1:8500', $options = []) | ||
| 26 | - { | ||
| 27 | - $this->options = $options; | ||
| 28 | - $this->sf = new ServiceFactory([ | ||
| 29 | - 'base_uri' => $uri | ||
| 30 | - ]); | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public function getName(): string | ||
| 34 | - { | ||
| 35 | - return 'Consul'; | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - /** | ||
| 39 | - * 注册节点 | ||
| 40 | - * | ||
| 41 | - * @param string $module | ||
| 42 | - * @param string $host | ||
| 43 | - * @param $port | ||
| 44 | - * @param int $weight | ||
| 45 | - * @author pengjch 202439 23:17:5 | ||
| 46 | - */ | ||
| 47 | - public function register($module, $host, $port, $weight = 1) | ||
| 48 | - { | ||
| 49 | - $id = $host . '_' . $port; | ||
| 50 | - /** @var Agent $agent */ | ||
| 51 | - $agent = $this->sf->get(AgentInterfaceAlias::class); | ||
| 52 | - $agent->registerService([ | ||
| 53 | - 'ID' => $id, | ||
| 54 | - 'Name' => $module, | ||
| 55 | - 'Port' => $port, | ||
| 56 | - 'Address' => $host, | ||
| 57 | - 'Tags' => [ | ||
| 58 | - 'port_' . $port, | ||
| 59 | - ], | ||
| 60 | - 'Weights' => [ | ||
| 61 | - 'Passing' => $weight, | ||
| 62 | - 'Warning' => 1, | ||
| 63 | - ], | ||
| 64 | - 'Check' => [ | ||
| 65 | - 'TCP' => $host . ':' . $port, | ||
| 66 | - 'Interval' => $this->options['interval'] ?? '10s', | ||
| 67 | - 'Timeout' => $this->options['timeout'] ?? '5s', | ||
| 68 | - 'DeregisterCriticalServiceAfter' => $this->options['deregisterCriticalServiceAfter'] ?? '30s', | ||
| 69 | - ], | ||
| 70 | - ]); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - /** | ||
| 74 | - * 注销节点 | ||
| 75 | - * http://127.0.0.1:8500/v1/agent/service/deregister/service_id | ||
| 76 | - * | ||
| 77 | - * @param $host | ||
| 78 | - * @param $port | ||
| 79 | - * @author pengjch 202439 23:16:51 | ||
| 80 | - */ | ||
| 81 | - public function unRegister($host, $port) | ||
| 82 | - { | ||
| 83 | - $id = $host . '_' . $port; | ||
| 84 | - /** @var Agent $agent */ | ||
| 85 | - $agent = $this->sf->get(AgentInterfaceAlias::class); | ||
| 86 | - $agent->deregisterService($id); | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - /** | ||
| 90 | - * 获取模块下所有的服务 | ||
| 91 | - * | ||
| 92 | - * @param string $module | ||
| 93 | - * @return array | ||
| 94 | - * @author pengjch 2024310 9:44:16 | ||
| 95 | - */ | ||
| 96 | - public function getServices(string $module): array | ||
| 97 | - { | ||
| 98 | - $cache = $this->serviceCache; | ||
| 99 | - $ttl = $this->options['ttl'] ?? $cache['ttl']; | ||
| 100 | - | ||
| 101 | - //本地缓存所有节点信息,避免每次请求都要从consul拉一遍数据 | ||
| 102 | - if ($cache['lastUpdateTime'] + $ttl < time()) { | ||
| 103 | - $health = new Health(); | ||
| 104 | - $servers = $health->service($module)->json(); | ||
| 105 | - if (empty($servers)) { | ||
| 106 | - return []; | ||
| 107 | - } | ||
| 108 | - $result = []; | ||
| 109 | - foreach ($servers as $server) { | ||
| 110 | - $result[] = Service::build($server['Service']['Address'], $server['Service']['Port'], $server['Service']['Weights']['Passing']); | ||
| 111 | - } | ||
| 112 | - $cache['service'] = $result; | ||
| 113 | - $cache['lastUpdateTime'] = time(); | ||
| 114 | - } | ||
| 115 | - | ||
| 116 | - return $cache['service']; | ||
| 117 | - } | ||
| 118 | - | ||
| 119 | - /** | ||
| 120 | - * 随机获取一个服务 | ||
| 121 | - * | ||
| 122 | - * @param string $module | ||
| 123 | - * @return Service | ||
| 124 | - * @author pengjch 2024310 9:44:27 | ||
| 125 | - */ | ||
| 126 | - public function getRandomService(string $module): Service | ||
| 127 | - { | ||
| 128 | - $services = $this->getServices($module); | ||
| 129 | - if (!$services) { | ||
| 130 | - throw new RpcException('It has not register module'); | ||
| 131 | - } | ||
| 132 | - | ||
| 133 | - return $services[rand(0, count($services) - 1)]; | ||
| 134 | - } | ||
| 135 | - | ||
| 136 | - /** | ||
| 137 | - * 获取权重服务 | ||
| 138 | - * | ||
| 139 | - * @param string $module | ||
| 140 | - * @return Service | ||
| 141 | - * @author pengjch 2024310 9:44:38 | ||
| 142 | - */ | ||
| 143 | - public function getWeightService(string $module): Service | ||
| 144 | - { | ||
| 145 | - $serviceArr = []; | ||
| 146 | - $totalWeight = 0; | ||
| 147 | - $services = $this->getServices($module); | ||
| 148 | - if (!$services) { | ||
| 149 | - throw new RpcException('It has not register module'); | ||
| 150 | - } | ||
| 151 | - | ||
| 152 | - /** @var Service $service */ | ||
| 153 | - foreach ($services as $service) { | ||
| 154 | - $totalWeight += $service->getWeight(); | ||
| 155 | - $sort[] = $service->getWeight(); | ||
| 156 | - $serviceArr[] = $service->toArray(); | ||
| 157 | - } | ||
| 158 | - | ||
| 159 | - array_multisort($serviceArr, SORT_DESC, $sort); | ||
| 160 | - | ||
| 161 | - $start = 0; | ||
| 162 | - $rand = rand(1, $totalWeight); | ||
| 163 | - foreach ($serviceArr as $service) { | ||
| 164 | - if ($start + $service['weight'] >= $rand) { | ||
| 165 | - return Service::build($service['host'], $service['port'], $service['weight']); | ||
| 166 | - } | ||
| 167 | - $start = $start + $service['weight']; | ||
| 168 | - } | ||
| 169 | - } | ||
| 170 | -} |
src/Register/RegisterInterface.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Register; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * Interface RegisterInterface | ||
| 8 | - * | ||
| 9 | - * @package AukeySwrpc\Register | ||
| 10 | - * @author pengjch 202439 16:23:35 | ||
| 11 | - */ | ||
| 12 | -interface RegisterInterface | ||
| 13 | -{ | ||
| 14 | - function getName(): string; | ||
| 15 | - | ||
| 16 | - function register($module, $host, $port, $weight = 1); | ||
| 17 | - | ||
| 18 | - function unRegister($host, $port); | ||
| 19 | - | ||
| 20 | - function getServices(string $module): array; | ||
| 21 | - | ||
| 22 | - function getRandomService(string $module): Service; | ||
| 23 | - | ||
| 24 | - function getWeightService(string $module): Service; | ||
| 25 | -} |
src/Register/Service.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Register; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 注册中心服务 | ||
| 8 | - * Class Service | ||
| 9 | - * | ||
| 10 | - * @package AukeySwrpc\Register | ||
| 11 | - * @author pengjch 2024311 10:25:46 | ||
| 12 | - */ | ||
| 13 | -class Service | ||
| 14 | -{ | ||
| 15 | - protected $host; | ||
| 16 | - protected $port; | ||
| 17 | - protected $weight; | ||
| 18 | - | ||
| 19 | - public function __construct($host, $port, $weight) | ||
| 20 | - { | ||
| 21 | - $this->host = $host; | ||
| 22 | - $this->port = $port; | ||
| 23 | - $this->weight = $weight; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public static function build($host, $port, $weight) | ||
| 27 | - { | ||
| 28 | - return new static($host, $port, $weight); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - public function getHost() | ||
| 32 | - { | ||
| 33 | - return $this->host; | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - public function getPort() | ||
| 37 | - { | ||
| 38 | - return $this->port; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - public function getWeight() | ||
| 42 | - { | ||
| 43 | - return $this->weight; | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | - public function toArray(): array | ||
| 47 | - { | ||
| 48 | - return [ | ||
| 49 | - 'host' => $this->host, | ||
| 50 | - 'port' => $this->port, | ||
| 51 | - 'weight' => $this->weight | ||
| 52 | - ]; | ||
| 53 | - } | ||
| 54 | -} |
src/Request/AsyncRequest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Request; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * Class AsyncRequest | ||
| 8 | - * | ||
| 9 | - * @package AukeySwrpc\Request | ||
| 10 | - * @author pengjch 2024313 9:10:2 | ||
| 11 | - */ | ||
| 12 | -class AsyncRequest extends Request | ||
| 13 | -{ | ||
| 14 | - public function init() | ||
| 15 | - { | ||
| 16 | - $this->setSync(false); | ||
| 17 | - $this->setSystem(false); | ||
| 18 | - } | ||
| 19 | -} |
src/Request/Request.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Request; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Tracer\TracerContext; | ||
| 7 | - | ||
| 8 | -abstract class Request | ||
| 9 | -{ | ||
| 10 | - protected string $module; | ||
| 11 | - protected string $method; | ||
| 12 | - protected array $params; | ||
| 13 | - protected bool $isSync = true; //是否同步请求,默认是 | ||
| 14 | - protected bool $isSystem = false; //是否系统请求,默认否 | ||
| 15 | - protected $error; | ||
| 16 | - protected ?TracerContext $traceContext; | ||
| 17 | - | ||
| 18 | - public static function create($method, $params, ?TracerContext $traceContext = null) | ||
| 19 | - { | ||
| 20 | - return new static ($method, $params, $traceContext); | ||
| 21 | - } | ||
| 22 | - | ||
| 23 | - public function __construct($method, $params, ?TracerContext $traceContext = null) | ||
| 24 | - { | ||
| 25 | - $this->method = $method; | ||
| 26 | - $this->params = $params; | ||
| 27 | - $this->traceContext = $traceContext; | ||
| 28 | - $this->init(); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - abstract public function init(); | ||
| 32 | - | ||
| 33 | - public function getModule(): string | ||
| 34 | - { | ||
| 35 | - return $this->module; | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - public function getMethod(): string | ||
| 39 | - { | ||
| 40 | - return $this->method; | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - public function getParams(): array | ||
| 44 | - { | ||
| 45 | - return $this->params; | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - public function setParams(array $params) | ||
| 49 | - { | ||
| 50 | - $this->params = $params; | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | - public function setModule(string $name) | ||
| 54 | - { | ||
| 55 | - $this->module = $name; | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - public function mergeParams(array $params) | ||
| 59 | - { | ||
| 60 | - $this->params = array_merge($this->params, $params); | ||
| 61 | - } | ||
| 62 | - | ||
| 63 | - public function getTraceContext(): ?TracerContext | ||
| 64 | - { | ||
| 65 | - return $this->traceContext; | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - public function setTraceContext($traceID, $parentID, $url) | ||
| 69 | - { | ||
| 70 | - $this->traceContext = TracerContext::create($traceID, $parentID, $url); | ||
| 71 | - } | ||
| 72 | - | ||
| 73 | - public function setSync(bool $value) | ||
| 74 | - { | ||
| 75 | - $this->isSync = $value; | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - public function isSync(): bool | ||
| 79 | - { | ||
| 80 | - return $this->isSync; | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | - public function setSystem(bool $value) | ||
| 84 | - { | ||
| 85 | - $this->isSystem = $value; | ||
| 86 | - } | ||
| 87 | - | ||
| 88 | - public function isSystem(): bool | ||
| 89 | - { | ||
| 90 | - return $this->isSystem; | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - public function getError() | ||
| 94 | - { | ||
| 95 | - return $this->error; | ||
| 96 | - } | ||
| 97 | - | ||
| 98 | - public function setError($err) | ||
| 99 | - { | ||
| 100 | - $this->error = $err; | ||
| 101 | - } | ||
| 102 | -} |
src/Request/SyncRequest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Request; | ||
| 4 | - | ||
| 5 | -/** | ||
| 6 | - * Class SyncRequest | ||
| 7 | - * | ||
| 8 | - * @package AukeySwrpc\Request | ||
| 9 | - * @author pengjch 2024313 9:9:54 | ||
| 10 | - */ | ||
| 11 | -class SyncRequest extends Request | ||
| 12 | -{ | ||
| 13 | - public function init() | ||
| 14 | - { | ||
| 15 | - $this->setSync(true); | ||
| 16 | - $this->setSystem(false); | ||
| 17 | - } | ||
| 18 | -} |
src/Request/SystemRequest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Request; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * Class AsyncRequest | ||
| 8 | - * | ||
| 9 | - * @package AukeySwrpc\Request | ||
| 10 | - * @author pengjch 2024313 9:10:2 | ||
| 11 | - */ | ||
| 12 | -class SystemRequest extends Request | ||
| 13 | -{ | ||
| 14 | - public function init() | ||
| 15 | - { | ||
| 16 | - $this->setSync(true); | ||
| 17 | - $this->setSystem(true); | ||
| 18 | - } | ||
| 19 | -} |
src/Response.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * Class Response | ||
| 8 | - * | ||
| 9 | - * @package AukeySwrpc | ||
| 10 | - * @author pengjch 202439 11:36:9 | ||
| 11 | - */ | ||
| 12 | -class Response | ||
| 13 | -{ | ||
| 14 | - const RES_ERROR = 0; | ||
| 15 | - const RES_SUCCESS = 1; | ||
| 16 | - | ||
| 17 | - public string $msg; | ||
| 18 | - public int $code; | ||
| 19 | - public array $data; | ||
| 20 | - | ||
| 21 | - public function __construct($code, $msg, $data) | ||
| 22 | - { | ||
| 23 | - $this->data = $data; | ||
| 24 | - $this->code = $code; | ||
| 25 | - $this->msg = $msg; | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - public static function error($msg, $code = self::RES_ERROR, $data = []): Response | ||
| 29 | - { | ||
| 30 | - return new static($code, $msg, $data); | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public static function success($data = [], $msg = 'success', $code = self::RES_SUCCESS): Response | ||
| 34 | - { | ||
| 35 | - return new static($code, $msg, $data); | ||
| 36 | - } | ||
| 37 | -} |
src/Server.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Monolog\Handler\StreamHandler; | ||
| 7 | -use Monolog\Logger; | ||
| 8 | -use Psr\Log\LoggerInterface; | ||
| 9 | -use AukeySwrpc\Middlewares\TraceMiddleware; | ||
| 10 | -use AukeySwrpc\Packer\SerializeLengthPacker; | ||
| 11 | -use AukeySwrpc\Register\RegisterInterface; | ||
| 12 | -use AukeySwrpc\Middlewares\MiddlewareInterface; | ||
| 13 | -use AukeySwrpc\Packer\PackerInterface; | ||
| 14 | -use AukeySwrpc\Request\Request; | ||
| 15 | - | ||
| 16 | -/** | ||
| 17 | - * Class Server | ||
| 18 | - * | ||
| 19 | - * @package AukeySwrpc | ||
| 20 | - * @author pengjch 202439 11:35:52 | ||
| 21 | - */ | ||
| 22 | -class Server | ||
| 23 | -{ | ||
| 24 | - use Event; | ||
| 25 | - | ||
| 26 | - protected string $module; | ||
| 27 | - protected string $host; | ||
| 28 | - protected int $port; | ||
| 29 | - protected int $weight = 1; | ||
| 30 | - protected array $options; | ||
| 31 | - protected array $defaultOptions | ||
| 32 | - = [ | ||
| 33 | - 'open_length_check' => true, | ||
| 34 | - 'package_length_type' => 'N', | ||
| 35 | - 'package_length_offset' => 0, //第N个字节是包长度的值 | ||
| 36 | - 'package_body_offset' => 4, //第几个字节开始计算长度 | ||
| 37 | - 'package_max_length' => 81920, //协议最大长度 | ||
| 38 | - ]; | ||
| 39 | - | ||
| 40 | - /** @var PackerInterface $packer */ | ||
| 41 | - protected $packer; | ||
| 42 | - | ||
| 43 | - /** @var Service $service */ | ||
| 44 | - protected $service; | ||
| 45 | - | ||
| 46 | - /** @var LoggerInterface $logger */ | ||
| 47 | - protected $logger; | ||
| 48 | - | ||
| 49 | - /** @var RegisterInterface $register */ | ||
| 50 | - protected $register; | ||
| 51 | - | ||
| 52 | - /** @var \Swoole\Server $server */ | ||
| 53 | - protected \Swoole\Server $server; | ||
| 54 | - | ||
| 55 | - private array $middlewares; | ||
| 56 | - | ||
| 57 | - public function __construct( | ||
| 58 | - string $module, | ||
| 59 | - string $host, | ||
| 60 | - int $port, | ||
| 61 | - array $options = [], | ||
| 62 | - $mode = SWOOLE_PROCESS, | ||
| 63 | - $socketType = SWOOLE_SOCK_TCP, | ||
| 64 | - LoggerInterface $logger = null | ||
| 65 | - ) { | ||
| 66 | - $this->module = $module; | ||
| 67 | - $this->host = $host; | ||
| 68 | - $this->port = $port; | ||
| 69 | - | ||
| 70 | - $this->setDefaultOptions($options); | ||
| 71 | - $this->setDefaultLogger($logger); | ||
| 72 | - $this->setCoreMiddleware(); | ||
| 73 | - | ||
| 74 | - $this->service = new Service($this->logger); | ||
| 75 | - | ||
| 76 | - $server = new \Swoole\Server($host, $port, $mode ?: SWOOLE_PROCESS, $socketType ?: SWOOLE_SOCK_TCP); | ||
| 77 | - $server->set($this->options); | ||
| 78 | - $server->on('Start', [$this, 'onStart']); | ||
| 79 | - $server->on('Shutdown', [$this, 'onShutdown']); | ||
| 80 | - $server->on('WorkerStart', [$this, 'onWorkerStart']); | ||
| 81 | - $server->on('Connect', [$this, 'OnConnect']); | ||
| 82 | - $server->on('Receive', [$this, 'OnReceive']); | ||
| 83 | - $server->on('Close', [$this, 'OnClose']); | ||
| 84 | - $server->on('Task', [$this, 'OnTask']); | ||
| 85 | - $server->on('Finish', [$this, 'OnFinish']); | ||
| 86 | - $this->server = $server; | ||
| 87 | - } | ||
| 88 | - | ||
| 89 | - /** | ||
| 90 | - * 设置节点权重 | ||
| 91 | - * | ||
| 92 | - * @param int $weight | ||
| 93 | - * @return Server | ||
| 94 | - * @author pengjch 2024313 10:55:39 | ||
| 95 | - */ | ||
| 96 | - public function weight(int $weight): Server | ||
| 97 | - { | ||
| 98 | - $this->weight = $weight; | ||
| 99 | - return $this; | ||
| 100 | - } | ||
| 101 | - | ||
| 102 | - /** | ||
| 103 | - * 设置默认选项 | ||
| 104 | - * | ||
| 105 | - * @param $options | ||
| 106 | - * @author pengjch 2024311 10:35:3 | ||
| 107 | - */ | ||
| 108 | - protected function setDefaultOptions($options) | ||
| 109 | - { | ||
| 110 | - if (empty($options)) { | ||
| 111 | - $options = $this->defaultOptions; | ||
| 112 | - } | ||
| 113 | - | ||
| 114 | - $this->options = $options; | ||
| 115 | - | ||
| 116 | - //请求数量超过10000重启 | ||
| 117 | - if (empty($this->options['max_request'])) { | ||
| 118 | - $this->options['max_request'] = 10000; | ||
| 119 | - } | ||
| 120 | - //默认task数量 | ||
| 121 | - if (empty($this->options['task_worker_num'])) { | ||
| 122 | - $this->options['task_worker_num'] = swoole_cpu_num() * 2; | ||
| 123 | - } | ||
| 124 | - //task请求数超过10000则重启 | ||
| 125 | - if (empty($this->options['task_max_request'])) { | ||
| 126 | - $this->options['task_max_request'] = 10000; | ||
| 127 | - } | ||
| 128 | - //10s没有数据传输就进行检测 | ||
| 129 | - if (empty($this->options['tcp_keepidle'])) { | ||
| 130 | - $this->options['tcp_keepidle'] = 10; | ||
| 131 | - } | ||
| 132 | - //3s探测一次 | ||
| 133 | - if (empty($this->options['tcp_keepinterval'])) { | ||
| 134 | - $this->options['tcp_keepinterval'] = 3; | ||
| 135 | - } | ||
| 136 | - //探测的次数,超过5次后还没回包close此连接 | ||
| 137 | - if (empty($this->options['tcp_keepcount'])) { | ||
| 138 | - $this->options['tcp_keepcount'] = 5; | ||
| 139 | - } | ||
| 140 | - } | ||
| 141 | - | ||
| 142 | - /** | ||
| 143 | - * 设置默认日志处理器 | ||
| 144 | - * | ||
| 145 | - * @param LoggerInterface|null $logger | ||
| 146 | - * @author pengjch 2024311 10:34:19 | ||
| 147 | - */ | ||
| 148 | - protected function setDefaultLogger(LoggerInterface $logger = null) | ||
| 149 | - { | ||
| 150 | - if (empty($logger)) { | ||
| 151 | - $logger = new Logger('AukeySwrpc'); | ||
| 152 | - $logger->pushHandler(new StreamHandler(STDOUT, Logger::DEBUG)); | ||
| 153 | - } | ||
| 154 | - $this->logger = $logger; | ||
| 155 | - } | ||
| 156 | - | ||
| 157 | - /** | ||
| 158 | - * 设置核心中间件 | ||
| 159 | - * | ||
| 160 | - * @author pengjch 2024311 10:34:5 | ||
| 161 | - */ | ||
| 162 | - protected function setCoreMiddleware() | ||
| 163 | - { | ||
| 164 | - $this->middlewares[] = TraceMiddleware::class; | ||
| 165 | - } | ||
| 166 | - | ||
| 167 | - /** | ||
| 168 | - * 添加中间件,支持匿名函数和实现类 | ||
| 169 | - * addMiddleware | ||
| 170 | - * | ||
| 171 | - * @param mixed ...$middlewares | ||
| 172 | - * @author pengjch 202439 11:35:11 | ||
| 173 | - */ | ||
| 174 | - public function addMiddleware(...$middlewares) | ||
| 175 | - { | ||
| 176 | - foreach ($middlewares as $middleware) { | ||
| 177 | - if (is_string($middleware) && class_exists($middleware)) { | ||
| 178 | - $middleware = new $middleware(); | ||
| 179 | - } | ||
| 180 | - if (!($middleware instanceof \Closure) && !($middleware instanceof MiddlewareInterface)) { | ||
| 181 | - $this->logger->warning('Skip illegal Middleware.'); | ||
| 182 | - continue; | ||
| 183 | - } | ||
| 184 | - $this->middlewares[] = $middleware; | ||
| 185 | - } | ||
| 186 | - } | ||
| 187 | - | ||
| 188 | - /** | ||
| 189 | - * 添加服务 | ||
| 190 | - * addService | ||
| 191 | - * | ||
| 192 | - * @param $service | ||
| 193 | - * @param string $prefix | ||
| 194 | - * @return Server | ||
| 195 | - * @author pengjch 202439 11:35:2 | ||
| 196 | - */ | ||
| 197 | - public function addService($service, $prefix = ''): Server | ||
| 198 | - { | ||
| 199 | - $this->service->addInstance($service, $prefix); | ||
| 200 | - return $this; | ||
| 201 | - } | ||
| 202 | - | ||
| 203 | - /** | ||
| 204 | - * @param $key | ||
| 205 | - * @return mixed|null | ||
| 206 | - * @author pengjch 2024312 16:11:12 | ||
| 207 | - */ | ||
| 208 | - public function getService($key) | ||
| 209 | - { | ||
| 210 | - return $this->service->getService($key); | ||
| 211 | - } | ||
| 212 | - | ||
| 213 | - /** | ||
| 214 | - * 注册发现中心 | ||
| 215 | - * | ||
| 216 | - * @param $register | ||
| 217 | - * @return Server | ||
| 218 | - * @author pengjch 202439 16:38:51 | ||
| 219 | - */ | ||
| 220 | - public function addRegister($register): Server | ||
| 221 | - { | ||
| 222 | - $this->register = $register; | ||
| 223 | - return $this; | ||
| 224 | - } | ||
| 225 | - | ||
| 226 | - /** | ||
| 227 | - * 添加日志处理器 | ||
| 228 | - * | ||
| 229 | - * @param $logger | ||
| 230 | - * @author pengjch 202439 12:20:57 | ||
| 231 | - */ | ||
| 232 | - public function addLogger($logger) | ||
| 233 | - { | ||
| 234 | - $this->logger = $logger; | ||
| 235 | - } | ||
| 236 | - | ||
| 237 | - /** | ||
| 238 | - * 添加包解析器 | ||
| 239 | - * | ||
| 240 | - * @param $packer | ||
| 241 | - * @author pengjch 202439 12:45:53 | ||
| 242 | - */ | ||
| 243 | - public function addPacker($packer) | ||
| 244 | - { | ||
| 245 | - $this->packer = $packer; | ||
| 246 | - } | ||
| 247 | - | ||
| 248 | - /** | ||
| 249 | - * 注册服务到consul | ||
| 250 | - * onWorkerStart 和 onStart 回调是在不同进程中并行执行的,不存在先后顺序 | ||
| 251 | - * | ||
| 252 | - * @param \Swoole\Server $server | ||
| 253 | - * @author pengjch 202439 23:11:10 | ||
| 254 | - */ | ||
| 255 | - public function onStart(\Swoole\Server $server) | ||
| 256 | - { | ||
| 257 | - if ($this->register) { | ||
| 258 | - $this->logger->info(sprintf('Register server[%s:%d] to %s.', $this->host, $this->port, $this->register->getName())); | ||
| 259 | - $this->register->register($this->module, $this->host, $this->port, $this->weight); | ||
| 260 | - } | ||
| 261 | - } | ||
| 262 | - | ||
| 263 | - /** | ||
| 264 | - * 注销服务 | ||
| 265 | - * 强制 kill 进程不会回调 onShutdown | ||
| 266 | - * 需要使用 kill -15 来发送 SIGTERM 信号到主进程才能按照正常的流程终止 | ||
| 267 | - * | ||
| 268 | - * @param \Swoole\Server $server | ||
| 269 | - * @author pengjch 202439 23:14:40 | ||
| 270 | - */ | ||
| 271 | - public function onShutdown(\Swoole\Server $server) | ||
| 272 | - { | ||
| 273 | - if ($this->register) { | ||
| 274 | - $this->logger->info(sprintf('UnRegister server[%s:%d] from register.', $this->host, $this->port)); | ||
| 275 | - $this->register->unRegister($this->host, $this->port); | ||
| 276 | - } | ||
| 277 | - } | ||
| 278 | - | ||
| 279 | - /** | ||
| 280 | - * server接收请求 | ||
| 281 | - * | ||
| 282 | - * @param \Swoole\Server $server | ||
| 283 | - * @param $fd | ||
| 284 | - * @param $reactor_id | ||
| 285 | - * @param $data | ||
| 286 | - * @return mixed | ||
| 287 | - * @author pengjch 202439 11:34:0 | ||
| 288 | - */ | ||
| 289 | - public function onReceive(\Swoole\Server $server, $fd, $reactor_id, $data) | ||
| 290 | - { | ||
| 291 | - /** @var Request $request */ | ||
| 292 | - $request = $this->packer->unpack($data); | ||
| 293 | - //系统请求 | ||
| 294 | - if ($request->isSystem()) { | ||
| 295 | - return $server->send($fd, serialize($this->doSystemRequest($request))); | ||
| 296 | - } | ||
| 297 | - //同步请求 | ||
| 298 | - if ($request->isSync()) { | ||
| 299 | - return $server->send($fd, serialize($this->doRequest($request))); | ||
| 300 | - } | ||
| 301 | - //异步请求 | ||
| 302 | - $server->task($request); | ||
| 303 | - return $server->send($fd, serialize(Response::success(['result' => 'success']))); | ||
| 304 | - } | ||
| 305 | - | ||
| 306 | - /** | ||
| 307 | - * 执行请求 | ||
| 308 | - * | ||
| 309 | - * @param Request $request | ||
| 310 | - * @return Response | ||
| 311 | - * @author pengjch 2024313 9:37:20 | ||
| 312 | - */ | ||
| 313 | - public function doRequest(Request $request): Response | ||
| 314 | - { | ||
| 315 | - try { | ||
| 316 | - $handler = $this->getRequestHandler(); | ||
| 317 | - } catch (\ReflectionException $e) { | ||
| 318 | - return Response::error($e->getMessage()); | ||
| 319 | - } | ||
| 320 | - | ||
| 321 | - $response = $handler($request); | ||
| 322 | - if (!($response instanceof Response)) { | ||
| 323 | - $msg = 'The middleware must return the response type'; | ||
| 324 | - $this->logger->error($msg); | ||
| 325 | - $response = Response::error($msg); | ||
| 326 | - } | ||
| 327 | - | ||
| 328 | - return $response; | ||
| 329 | - } | ||
| 330 | - | ||
| 331 | - /** | ||
| 332 | - * 系统请求 | ||
| 333 | - * | ||
| 334 | - * @param Request $request | ||
| 335 | - * @return Response | ||
| 336 | - * @author pengjch 2024323 10:46:55 | ||
| 337 | - */ | ||
| 338 | - public function doSystemRequest(Request $request): Response | ||
| 339 | - { | ||
| 340 | - if ($request->getMethod() == 'stats') { | ||
| 341 | - return Response::success(['result' => $this->server->stats()]); | ||
| 342 | - } else { | ||
| 343 | - return Response::error($request->getMethod() . ' is not supported'); | ||
| 344 | - } | ||
| 345 | - } | ||
| 346 | - | ||
| 347 | - /** | ||
| 348 | - * @return mixed | ||
| 349 | - * @throws \ReflectionException | ||
| 350 | - * @author pengjch 2024312 16:36:52 | ||
| 351 | - */ | ||
| 352 | - public function getRequestHandler() | ||
| 353 | - { | ||
| 354 | - return array_reduce(array_reverse($this->middlewares), function ($stack, $next) { | ||
| 355 | - return function ($request) use ($stack, $next) { | ||
| 356 | - if ($next instanceof \Closure) { | ||
| 357 | - return $next($request, $stack); | ||
| 358 | - } elseif (is_string($next) && class_exists($next)) { | ||
| 359 | - return (new $next())->handle($request, $stack); | ||
| 360 | - } else { | ||
| 361 | - return $next->handle($request, $stack); | ||
| 362 | - } | ||
| 363 | - }; | ||
| 364 | - }, function ($request) { | ||
| 365 | - return $this->service->call($request); | ||
| 366 | - }); | ||
| 367 | - } | ||
| 368 | - | ||
| 369 | - /** | ||
| 370 | - * 异步处理请求 | ||
| 371 | - * | ||
| 372 | - * @param $server | ||
| 373 | - * @param $taskID | ||
| 374 | - * @param $reactorID | ||
| 375 | - * @param $data | ||
| 376 | - * @return Response | ||
| 377 | - * @author pengjch 2024313 9:40:37 | ||
| 378 | - */ | ||
| 379 | - public function OnTask($server, $taskID, $reactorID, $data): Response | ||
| 380 | - { | ||
| 381 | - $this->logger->debug('AsyncTask: Start', ['taskID' => $taskID]); | ||
| 382 | - return $this->doRequest($data); | ||
| 383 | - } | ||
| 384 | - | ||
| 385 | - /** | ||
| 386 | - * 完成异步任务回调 | ||
| 387 | - * | ||
| 388 | - * @param $server | ||
| 389 | - * @param $taskID | ||
| 390 | - * @param $data | ||
| 391 | - * @author pengjch 2024313 9:49:44 | ||
| 392 | - */ | ||
| 393 | - public function OnFinish($server, $taskID, $data) | ||
| 394 | - { | ||
| 395 | - $this->logger->debug('AsyncTask: Finish', ['taskID' => $taskID, 'data' => $data]); | ||
| 396 | - } | ||
| 397 | - | ||
| 398 | - /** | ||
| 399 | - * OnClose | ||
| 400 | - * | ||
| 401 | - * @param $server | ||
| 402 | - * @param $fd | ||
| 403 | - * @author pengjch 202439 11:34:48 | ||
| 404 | - */ | ||
| 405 | - public function OnClose($server, $fd) | ||
| 406 | - { | ||
| 407 | - $this->logger->debug('Client: Close'); | ||
| 408 | - } | ||
| 409 | - | ||
| 410 | - /** | ||
| 411 | - * OnConnect | ||
| 412 | - * | ||
| 413 | - * @param $server | ||
| 414 | - * @param $fd | ||
| 415 | - * @author pengjch 202439 11:34:52 | ||
| 416 | - */ | ||
| 417 | - public function OnConnect($server, $fd) | ||
| 418 | - { | ||
| 419 | - $this->logger->debug('Client: Connect.'); | ||
| 420 | - } | ||
| 421 | - | ||
| 422 | - /** | ||
| 423 | - * start | ||
| 424 | - * | ||
| 425 | - * @author pengjch 202439 11:34:56 | ||
| 426 | - */ | ||
| 427 | - public function start(): bool | ||
| 428 | - { | ||
| 429 | - //可用服务数量 | ||
| 430 | - if ($this->service->count() == 0) { | ||
| 431 | - $this->logger->error('There is no service available.'); | ||
| 432 | - return false; | ||
| 433 | - } | ||
| 434 | - //默认使用固定包头+包体方式解决粘包问题 | ||
| 435 | - if (empty($this->packer)) { | ||
| 436 | - $this->packer = new SerializeLengthPacker([ | ||
| 437 | - 'package_length_type' => $this->options['package_length_type'] ?? 'N', | ||
| 438 | - 'package_body_offset' => $this->options['package_body_offset'] ?? 4, | ||
| 439 | - ]); | ||
| 440 | - } | ||
| 441 | - | ||
| 442 | - $this->logger->info(sprintf('Rpc server[%s:%s] start.', $this->host, $this->port)); | ||
| 443 | - $this->server->start(); | ||
| 444 | - return true; | ||
| 445 | - } | ||
| 446 | -} |
src/Service.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Psr\Log\LoggerInterface; | ||
| 7 | -use ReflectionClass; | ||
| 8 | -use ReflectionMethod; | ||
| 9 | -use AukeySwrpc\Request\Request; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * Class Service | ||
| 13 | - * | ||
| 14 | - * @package AukeySwrpc | ||
| 15 | - * @author pengjch 202439 11:39:41 | ||
| 16 | - */ | ||
| 17 | -class Service | ||
| 18 | -{ | ||
| 19 | - private array $services = []; | ||
| 20 | - protected array $filers | ||
| 21 | - = [ | ||
| 22 | - 'factory', | ||
| 23 | - 'initTracer', | ||
| 24 | - 'setModule', | ||
| 25 | - 'setTracerUrl', | ||
| 26 | - 'setParams', | ||
| 27 | - 'setTracerContext', | ||
| 28 | - 'getTracerContext' | ||
| 29 | - ]; | ||
| 30 | - | ||
| 31 | - /** @var LoggerInterface $logger */ | ||
| 32 | - private $logger; | ||
| 33 | - | ||
| 34 | - public function __construct($logger) | ||
| 35 | - { | ||
| 36 | - $this->logger = $logger; | ||
| 37 | - } | ||
| 38 | - | ||
| 39 | - /** | ||
| 40 | - * 注册服务实例 | ||
| 41 | - * | ||
| 42 | - * @param $obj | ||
| 43 | - * @param $prefix | ||
| 44 | - * @return bool | ||
| 45 | - * @author pengjch 202438 13:43:21 | ||
| 46 | - */ | ||
| 47 | - public function addInstance($obj, $prefix = ''): bool | ||
| 48 | - { | ||
| 49 | - if (is_string($obj)) { | ||
| 50 | - $obj = new $obj(); | ||
| 51 | - } | ||
| 52 | - if (!is_object($obj)) { | ||
| 53 | - $this->logger->error('Service is not an object.', ['service' => $obj]); | ||
| 54 | - return false; | ||
| 55 | - } | ||
| 56 | - if (!($obj instanceof LogicService)) { | ||
| 57 | - $this->logger->error('The Service does not inherit LogicService', ['service' => get_class($obj)]); | ||
| 58 | - return false; | ||
| 59 | - } | ||
| 60 | - $className = get_class($obj); | ||
| 61 | - $methods = get_class_methods($obj); | ||
| 62 | - foreach ($methods as $method) { | ||
| 63 | - if (in_array($method, $this->filers)) { | ||
| 64 | - continue; | ||
| 65 | - } | ||
| 66 | - if (strlen($prefix) > 0) { | ||
| 67 | - $key = $prefix . '_' . $className . '_' . $method; | ||
| 68 | - } else { | ||
| 69 | - $key = $className . '_' . $method; | ||
| 70 | - } | ||
| 71 | - $this->services[$key] = $className; | ||
| 72 | - $this->logger->info(sprintf('import %s => %s.', $key, $className)); | ||
| 73 | - } | ||
| 74 | - | ||
| 75 | - return true; | ||
| 76 | - } | ||
| 77 | - | ||
| 78 | - /** | ||
| 79 | - * 获取服务 | ||
| 80 | - * | ||
| 81 | - * @param $key | ||
| 82 | - * @return mixed|null | ||
| 83 | - * @author pengjch 202438 13:43:17 | ||
| 84 | - */ | ||
| 85 | - public function getService($key) | ||
| 86 | - { | ||
| 87 | - return $this->services[$key] ?? null; | ||
| 88 | - } | ||
| 89 | - | ||
| 90 | - /** | ||
| 91 | - * 获取所有服务 | ||
| 92 | - * getServices | ||
| 93 | - * | ||
| 94 | - * @return array | ||
| 95 | - * @author pengjch 202438 15:23:58 | ||
| 96 | - */ | ||
| 97 | - public function getServices(): array | ||
| 98 | - { | ||
| 99 | - return $this->services; | ||
| 100 | - } | ||
| 101 | - | ||
| 102 | - /** | ||
| 103 | - * count | ||
| 104 | - * | ||
| 105 | - * @return int | ||
| 106 | - * @author pengjch 202439 12:56:46 | ||
| 107 | - */ | ||
| 108 | - public function count(): int | ||
| 109 | - { | ||
| 110 | - return count($this->services); | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - /** | ||
| 114 | - * @param $key | ||
| 115 | - * @return bool | ||
| 116 | - * @author pengjch 202438 14:32:50 | ||
| 117 | - */ | ||
| 118 | - public function isExist($key): bool | ||
| 119 | - { | ||
| 120 | - return isset($this->services[$key]); | ||
| 121 | - } | ||
| 122 | - | ||
| 123 | - /** | ||
| 124 | - * 调用服务 | ||
| 125 | - * | ||
| 126 | - * @param Request $request | ||
| 127 | - * @return Response | ||
| 128 | - * @throws \ReflectionException | ||
| 129 | - * @author pengjch 202439 10:17:59 | ||
| 130 | - */ | ||
| 131 | - public function call(Request $request): Response | ||
| 132 | - { | ||
| 133 | - if ($err = $request->getError()) { | ||
| 134 | - return Response::error($err); | ||
| 135 | - } | ||
| 136 | - | ||
| 137 | - $service = $this->getService($request->getMethod()); | ||
| 138 | - if (!$service) { | ||
| 139 | - $this->logger->debug('service is not exist.', ['method' => $request->getMethod()]); | ||
| 140 | - return Response::error('service is not exist.'); | ||
| 141 | - } | ||
| 142 | - | ||
| 143 | - $methodArr = explode('_', $request->getMethod()); | ||
| 144 | - $methodName = array_pop($methodArr); | ||
| 145 | - $reflect = new ReflectionClass($service); | ||
| 146 | - $instance = $reflect->newInstanceArgs(); | ||
| 147 | - if (!method_exists($instance, $methodName)) { | ||
| 148 | - $this->logger->debug('method is not exist.', ['method' => $request->getMethod()]); | ||
| 149 | - return Response::error(sprintf('%s method[%s] is not exist.', $service, $methodName)); | ||
| 150 | - } | ||
| 151 | - | ||
| 152 | - $ctx = $request->getTraceContext(); | ||
| 153 | - if ($ctx && method_exists($instance, 'setTracerContext')) { | ||
| 154 | - $instance->setTracerUrl($ctx->getReporterUrl())->setTracerContext($ctx); | ||
| 155 | - } | ||
| 156 | - | ||
| 157 | - try { | ||
| 158 | - $methodObj = new ReflectionMethod($reflect->getName(), $methodName); | ||
| 159 | - $result = $methodObj->invokeArgs($instance, $request->getParams()); | ||
| 160 | - } catch (\Throwable $e) { | ||
| 161 | - return Response::error($e->getMessage()); | ||
| 162 | - } | ||
| 163 | - | ||
| 164 | - return Response::success([ | ||
| 165 | - 'result' => $result | ||
| 166 | - ]); | ||
| 167 | - } | ||
| 168 | -} |
src/Tracer/TracerContext.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpc\Tracer; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * 链路追踪上下文 | ||
| 8 | - * Class TracerContext | ||
| 9 | - * | ||
| 10 | - * @package AukeySwrpc\Tracer | ||
| 11 | - * @author pengjch 2024311 10:21:34 | ||
| 12 | - */ | ||
| 13 | -class TracerContext | ||
| 14 | -{ | ||
| 15 | - protected $traceID; | ||
| 16 | - protected $parentID; | ||
| 17 | - protected $reporterUrl; | ||
| 18 | - | ||
| 19 | - public function __construct($traceID, $parentID, $reporterUrl) | ||
| 20 | - { | ||
| 21 | - $this->traceID = $traceID; | ||
| 22 | - $this->parentID = $parentID; | ||
| 23 | - $this->reporterUrl = $reporterUrl; | ||
| 24 | - } | ||
| 25 | - | ||
| 26 | - public static function create($traceID, $parentID, $reporterUrl) | ||
| 27 | - { | ||
| 28 | - return new static($traceID, $parentID, $reporterUrl); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - public function setTraceID($traceID) | ||
| 32 | - { | ||
| 33 | - $this->traceID = $traceID; | ||
| 34 | - } | ||
| 35 | - | ||
| 36 | - public function setParentID($parentID) | ||
| 37 | - { | ||
| 38 | - $this->parentID = $parentID; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - public function setReporterUrl($url) | ||
| 42 | - { | ||
| 43 | - $this->reporterUrl = $url; | ||
| 44 | - } | ||
| 45 | - | ||
| 46 | - public function getTraceID() | ||
| 47 | - { | ||
| 48 | - return $this->traceID; | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - public function getParentID() | ||
| 52 | - { | ||
| 53 | - return $this->parentID; | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - public function getReporterUrl() | ||
| 57 | - { | ||
| 58 | - return $this->reporterUrl; | ||
| 59 | - } | ||
| 60 | -} |
tests/BootTest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use PHPUnit\Framework\TestCase; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * Class BootTest | ||
| 10 | - * | ||
| 11 | - * @author wuzhc | ||
| 12 | - * @internal | ||
| 13 | - */ | ||
| 14 | -abstract class BootTest extends TestCase | ||
| 15 | -{ | ||
| 16 | - const PID_FILE = __DIR__ . '/AukeySwrpc.pid'; | ||
| 17 | - const SERVER_LOG = __DIR__ . '/AukeySwrpc.log'; | ||
| 18 | - const SERVER_SCRIPT = __DIR__ . '/server.sh'; | ||
| 19 | - | ||
| 20 | - public static function setUpBeforeClass(): void | ||
| 21 | - { | ||
| 22 | - // fwrite(STDOUT, 'Starting rpc server...' . PHP_EOL); | ||
| 23 | - $cmd = 'nohup ' . self::SERVER_SCRIPT . ' > ' . self::SERVER_LOG . ' 2>&1 &'; | ||
| 24 | - shell_exec($cmd); | ||
| 25 | - sleep(5); | ||
| 26 | - | ||
| 27 | - self::assertFileExists(self::PID_FILE, 'Run rpc server failed: ' . $cmd . ''); | ||
| 28 | - $pid = file_get_contents(self::PID_FILE); | ||
| 29 | - self::assertNotEmpty($pid, 'Failed to start the rpc server.'); | ||
| 30 | - | ||
| 31 | - $res = shell_exec('ps aux | grep ' . $pid . ' | wc -l'); | ||
| 32 | - self::assertGreaterThanOrEqual(1, intval($res), 'Failed to start the rpc server.'); | ||
| 33 | - | ||
| 34 | - // fwrite(STDOUT, 'Rpc server started successfully.' . PHP_EOL); | ||
| 35 | - } | ||
| 36 | - | ||
| 37 | - public static function tearDownAfterClass(): void | ||
| 38 | - { | ||
| 39 | - if (\file_exists(self::PID_FILE)) { | ||
| 40 | - $pid = file_get_contents(self::PID_FILE); | ||
| 41 | - \shell_exec('kill -15 ' . $pid); | ||
| 42 | - if (\file_exists(self::PID_FILE)) { | ||
| 43 | - \unlink(self::PID_FILE); | ||
| 44 | - } | ||
| 45 | - \sleep(1); | ||
| 46 | - } | ||
| 47 | - } | ||
| 48 | -} |
tests/ClientTest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Register\Consul; | ||
| 7 | -use AukeySwrpc\Register\Service; | ||
| 8 | -use AukeySwrpc\Request; | ||
| 9 | -use AukeySwrpc\Client; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * 客户端单元测试 | ||
| 13 | - * php74 ../phpunit.phar tests/ClientTest.php --debug | ||
| 14 | - * Class ClientTest | ||
| 15 | - * | ||
| 16 | - * @link http://www.phpunit.cn/manual/7.0/zh_cn/index.html | ||
| 17 | - * @author pengjch 2024312 9:39:22 | ||
| 18 | - */ | ||
| 19 | -class ClientTest extends BootTest | ||
| 20 | -{ | ||
| 21 | - /** | ||
| 22 | - * @return Client Client | ||
| 23 | - * @author pengjch 2024312 14:29:28 | ||
| 24 | - */ | ||
| 25 | - public function testClientConnect(): Client | ||
| 26 | - { | ||
| 27 | - $client = Client::create('School_Module', getenv('RPC_SERVER_HOST'), getenv('RPC_SERVER_PORT')); | ||
| 28 | - $conn = $client->connect(); | ||
| 29 | - $this->assertIsBool($conn->isConnected(), 'Client connect failure.'); | ||
| 30 | - return $client; | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - /** | ||
| 34 | - * @depends testClientConnect | ||
| 35 | - * @param Client $client | ||
| 36 | - * @author pengjch 2024312 14:29:20 | ||
| 37 | - */ | ||
| 38 | - public function testClientSyncRequest($client) | ||
| 39 | - { | ||
| 40 | - $request = Request\SyncRequest::create('AukeySwrpcTests\services\SchoolService_getUserSchool', [1, 1]); | ||
| 41 | - $res = $client->send($request); | ||
| 42 | - $this->assertEquals('未来学校1', $res); | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - /** | ||
| 46 | - * @depends testClientConnect | ||
| 47 | - * @param $client | ||
| 48 | - * @author pengjch 2024313 10:3:43 | ||
| 49 | - */ | ||
| 50 | - public function testClientAsyncRequest($client) | ||
| 51 | - { | ||
| 52 | - $request = Request\AsyncRequest::create('AukeySwrpcTests\services\SchoolService_saveUserName', ['tony']); | ||
| 53 | - $res = $client->send($request); | ||
| 54 | - $this->assertEquals('success', $res); | ||
| 55 | - sleep(3); | ||
| 56 | - $this->assertFileExists('xxx.log', 'Async request failure.'); | ||
| 57 | - $value = file_get_contents('xxx.log'); | ||
| 58 | - $this->assertEquals('tony', $value); | ||
| 59 | - @unlink('xxx.log'); | ||
| 60 | - } | ||
| 61 | -} |
tests/PackerTest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use PHPUnit\Framework\TestCase; | ||
| 7 | -use AukeySwrpc\Request\SyncRequest; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * Class PackerTest | ||
| 11 | - * php74 ../phpunit.phar tests/ClientTest.php | ||
| 12 | - * | ||
| 13 | - * @package AukeySwrpcTests | ||
| 14 | - * @author pengjch 2024312 16:5:14 | ||
| 15 | - */ | ||
| 16 | -class PackerTest extends TestCase | ||
| 17 | -{ | ||
| 18 | - /** | ||
| 19 | - * 注意:Request类属性和方法发生变化时,这个测试案例就没有意义了 | ||
| 20 | - * @return string | ||
| 21 | - * @author pengjch 2024312 14:57:32 | ||
| 22 | - */ | ||
| 23 | - public function testSerializeLengthPack() | ||
| 24 | - { | ||
| 25 | - $packer = new \AukeySwrpc\Packer\SerializeLengthPacker(); | ||
| 26 | - $result = $packer->pack(SyncRequest::create('SchoolService_getName', [1, 1])); | ||
| 27 | - $this->assertEquals('AAAAzU86MjU6IlN3cnBjXFJlcXVlc3RcU3luY1JlcXVlc3QiOjY6e3M6OToiACoAbWV0aG9kIjtzOjIxOiJTY2hvb2xTZXJ2aWNlX2dldE5hbWUiO3M6OToiACoAcGFyYW1zIjthOjI6e2k6MDtpOjE7aToxO2k6MTt9czo5OiIAKgBpc1N5bmMiO2I6MTtzOjExOiIAKgBpc1N5c3RlbSI7YjowO3M6ODoiACoAZXJyb3IiO047czoxNToiACoAdHJhY2VDb250ZXh0IjtOO30=', base64_encode($result)); | ||
| 28 | - return base64_encode($result); | ||
| 29 | - } | ||
| 30 | - | ||
| 31 | - /** | ||
| 32 | - * @depends testSerializeLengthPack | ||
| 33 | - * @author pengjch 2024312 14:57:23 | ||
| 34 | - */ | ||
| 35 | - public function testSerializeLenghtUnpack($value) | ||
| 36 | - { | ||
| 37 | - $expect = SyncRequest::create('SchoolService_getName', [1, 1]); | ||
| 38 | - $packer = new \AukeySwrpc\Packer\SerializeLengthPacker(); | ||
| 39 | - $result = $packer->unpack(base64_decode($value)); | ||
| 40 | - $this->assertSame(serialize($expect), serialize($result)); | ||
| 41 | - } | ||
| 42 | - | ||
| 43 | - /** | ||
| 44 | - * 注意:Request类属性和方法发生变化时,这个测试案例就没有意义了 | ||
| 45 | - * @return string | ||
| 46 | - * @author pengjch 2024312 14:57:32 | ||
| 47 | - */ | ||
| 48 | - public function testSerializeEofPack() | ||
| 49 | - { | ||
| 50 | - $packer = new \AukeySwrpc\Packer\SerializeEofPacker(); | ||
| 51 | - $result = $packer->pack(SyncRequest::create('SchoolService_getName', [1, 1])); | ||
| 52 | - $this->assertEquals('TzoyNToiU3dycGNcUmVxdWVzdFxTeW5jUmVxdWVzdCI6Njp7czo5OiIAKgBtZXRob2QiO3M6MjE6IlNjaG9vbFNlcnZpY2VfZ2V0TmFtZSI7czo5OiIAKgBwYXJhbXMiO2E6Mjp7aTowO2k6MTtpOjE7aToxO31zOjk6IgAqAGlzU3luYyI7YjoxO3M6MTE6IgAqAGlzU3lzdGVtIjtiOjA7czo4OiIAKgBlcnJvciI7TjtzOjE1OiIAKgB0cmFjZUNvbnRleHQiO047fQ==', base64_encode($result)); | ||
| 53 | - return base64_encode($result); | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - /** | ||
| 57 | - * @depends testSerializeEofPack | ||
| 58 | - * @author pengjch 2024312 14:57:23 | ||
| 59 | - */ | ||
| 60 | - public function testSerializeEofUnpack($value) | ||
| 61 | - { | ||
| 62 | - $expect = SyncRequest::create('SchoolService_getName', [1, 1]); | ||
| 63 | - $packer = new \AukeySwrpc\Packer\SerializeEofPacker(); | ||
| 64 | - $result = $packer->unpack(base64_decode($value)); | ||
| 65 | - $this->assertSame(serialize($expect), serialize($result)); | ||
| 66 | - } | ||
| 67 | -} |
tests/ServerTest.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use Monolog\Logger; | ||
| 7 | -use AukeySwrpc\Register\Consul; | ||
| 8 | -use AukeySwrpc\Register\Service; | ||
| 9 | -use AukeySwrpc\Request\Request; | ||
| 10 | -use AukeySwrpc\Request\SyncRequest; | ||
| 11 | -use AukeySwrpc\Server; | ||
| 12 | -use AukeySwrpcTests\services\UserService; | ||
| 13 | - | ||
| 14 | -/** | ||
| 15 | - * Class ServerTest | ||
| 16 | - * php74 ../phpunit.phar tests/ClientTest.php | ||
| 17 | - * | ||
| 18 | - * @package AukeySwrpcTests | ||
| 19 | - * @author pengjch 2024312 16:5:7 | ||
| 20 | - */ | ||
| 21 | -class ServerTest extends \PHPUnit\Framework\TestCase | ||
| 22 | -{ | ||
| 23 | - /** | ||
| 24 | - * @author pengjch 2024312 17:8:31 | ||
| 25 | - */ | ||
| 26 | - public function testServerRegisterToConsul() | ||
| 27 | - { | ||
| 28 | - $res = shell_exec('netstat anp | grep ' . getenv('CONSUL_PORT') . ' | wc -l'); | ||
| 29 | - $this->assertGreaterThanOrEqual(1, intval($res), 'Warning: Consul not started.'); | ||
| 30 | - | ||
| 31 | - $consul = new Consul('http://' . getenv('CONSUL_HOST') . ':' . getenv('CONSUL_PORT')); | ||
| 32 | - $consul->register('test_module', '127.0.0.1', 8080); | ||
| 33 | - | ||
| 34 | - $isSuccess = false; | ||
| 35 | - $services = $consul->getServices('test_module'); | ||
| 36 | - /** @var Service $service */ | ||
| 37 | - foreach ($services as $service) { | ||
| 38 | - if ($service->getHost() == '127.0.0.1' && $service->getPort() == 8080) { | ||
| 39 | - $isSuccess = true; | ||
| 40 | - break; | ||
| 41 | - } | ||
| 42 | - } | ||
| 43 | - | ||
| 44 | - $this->assertIsBool($isSuccess); | ||
| 45 | - return $consul; | ||
| 46 | - } | ||
| 47 | - | ||
| 48 | - /** | ||
| 49 | - * @depends testServerRegisterToConsul | ||
| 50 | - * @param Consul $consul | ||
| 51 | - * @author pengjch 2024312 17:12:17 | ||
| 52 | - */ | ||
| 53 | - public function testServerUnregisterFromConsul($consul) | ||
| 54 | - { | ||
| 55 | - $consul->unRegister('127.0.0.1', 8080); | ||
| 56 | - $isSuccess = true; | ||
| 57 | - $services = $consul->getServices('test_module'); | ||
| 58 | - /** @var Service $service */ | ||
| 59 | - foreach ($services as $service) { | ||
| 60 | - if ($service->getHost() == '127.0.0.1' && $service->getPort() == 8080) { | ||
| 61 | - $isSuccess = false; | ||
| 62 | - break; | ||
| 63 | - } | ||
| 64 | - } | ||
| 65 | - $this->assertIsBool($isSuccess); | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - /** | ||
| 69 | - * @return Server | ||
| 70 | - * @author pengjch 2024312 17:8:17 | ||
| 71 | - */ | ||
| 72 | - public function testServerAddService() | ||
| 73 | - { | ||
| 74 | - $logger = new Logger('swprc'); | ||
| 75 | - $server = new Server('School_Module', getenv('RPC_SERVER_HOST'), getenv('RPC_SERVER_PORT'), [], null, null, $logger); | ||
| 76 | - $server->addService(UserService::class); | ||
| 77 | - $key = UserService::class . '_getName'; | ||
| 78 | - $value = $server->getService($key); | ||
| 79 | - $this->assertEquals(UserService::class, $value); | ||
| 80 | - return $server; | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | - /** | ||
| 84 | - * @depends testServerAddService | ||
| 85 | - * @param $server | ||
| 86 | - * @author pengjch 2024312 16:40:0 | ||
| 87 | - */ | ||
| 88 | - public function testServerAddMiddleware($server) | ||
| 89 | - { | ||
| 90 | - $request = SyncRequest::create('AukeySwrpcTests\services\UserService_getFavoriteFood', ['肥胖']); | ||
| 91 | - $server->addMiddleware(function (Request $request, $next) { | ||
| 92 | - $request->setParams(['帅气']); | ||
| 93 | - return $next($request); | ||
| 94 | - }); | ||
| 95 | - $func = $server->getRequestHandler(); | ||
| 96 | - $result = $func($request); | ||
| 97 | - $this->assertEquals('帅气的我喜欢吃苹果', $result->data['result']); | ||
| 98 | - } | ||
| 99 | -} |
tests/server.sh
已删除
100755 → 0
| 1 | -#!/usr/bin/env /opt/php74/bin/php | ||
| 2 | -<?php | ||
| 3 | - | ||
| 4 | -use AukeySwrpc\Register\Consul; | ||
| 5 | -use AukeySwrpc\Server; | ||
| 6 | - | ||
| 7 | -$basePath = dirname(dirname(__FILE__)); | ||
| 8 | -require_once $basePath . "/vendor/autoload.php"; | ||
| 9 | - | ||
| 10 | -$options = [ | ||
| 11 | - 'enable_coroutine' => true, | ||
| 12 | - 'pid_file' => __DIR__ . '/AukeySwrpc.pid', | ||
| 13 | -]; | ||
| 14 | -$server = new Server('School_Module', getenv('RPC_SERVER_HOST'), getenv('RPC_SERVER_PORT'), $options); | ||
| 15 | -$server->addRegister(new Consul()) | ||
| 16 | - ->addService(\AukeySwrpcTests\services\UserService::class) | ||
| 17 | - ->addService(\AukeySwrpcTests\services\SchoolService::class) | ||
| 18 | - ->addService(\AukeySwrpcTests\services\ClassService::class) | ||
| 19 | - ->start(); |
tests/services/ClassService.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests\services; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Exceptions\RpcException; | ||
| 7 | -use AukeySwrpc\LogicService; | ||
| 8 | -use AukeySwrpc\Register\Consul; | ||
| 9 | -use AukeySwrpc\Request\SyncRequest; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * Class ClassService | ||
| 13 | - * | ||
| 14 | - * @package AukeySwrpcTests\services | ||
| 15 | - * @author pengjch 2024313 9:15:21 | ||
| 16 | - */ | ||
| 17 | -class ClassService extends LogicService | ||
| 18 | -{ | ||
| 19 | - public function getUserClass($userID = 1): string | ||
| 20 | - { | ||
| 21 | - $register = new Consul(); | ||
| 22 | - try { | ||
| 23 | - $classID = 111; | ||
| 24 | - $client = \AukeySwrpc\Client::createBalancer('School_Module', $register, \AukeySwrpc\Client::STRATEGY_WEIGHT); | ||
| 25 | - $result = $client->send(SyncRequest::create('SchoolService_getUserSchool', [ | ||
| 26 | - $userID, | ||
| 27 | - $classID, | ||
| 28 | - ], $this->getTracerContext(__FUNCTION__))); | ||
| 29 | - } catch (RpcException $e) { | ||
| 30 | - return $e->getMessage() . PHP_EOL; | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - return '高一2班, school:' . $result; | ||
| 34 | - } | ||
| 35 | -} |
tests/services/SchoolService.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests\services; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\LogicService; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * Class SchoolService | ||
| 10 | - * | ||
| 11 | - * @package AukeySwrpcTests\services | ||
| 12 | - * @author pengjch 2024313 9:15:30 | ||
| 13 | - */ | ||
| 14 | -class SchoolService extends LogicService | ||
| 15 | -{ | ||
| 16 | - public function getUserSchool($userID, $classID): string | ||
| 17 | - { | ||
| 18 | - return '未来学校' . $userID; | ||
| 19 | - } | ||
| 20 | - | ||
| 21 | - public function saveUserName($name) | ||
| 22 | - { | ||
| 23 | - file_put_contents('xxx.log', $name); | ||
| 24 | - } | ||
| 25 | -} |
tests/services/UserService.php
已删除
100755 → 0
| 1 | -<?php | ||
| 2 | - | ||
| 3 | -namespace AukeySwrpcTests\services; | ||
| 4 | - | ||
| 5 | - | ||
| 6 | -use AukeySwrpc\Exceptions\RpcException; | ||
| 7 | -use AukeySwrpc\LogicService; | ||
| 8 | -use AukeySwrpc\Register\Consul; | ||
| 9 | -use AukeySwrpc\Request\SyncRequest; | ||
| 10 | - | ||
| 11 | -/** | ||
| 12 | - * Class UserService | ||
| 13 | - * | ||
| 14 | - * @package AukeySwrpcTests\services | ||
| 15 | - * @author pengjch 2024313 9:15:52 | ||
| 16 | - */ | ||
| 17 | -class UserService extends LogicService | ||
| 18 | -{ | ||
| 19 | - /** | ||
| 20 | - * @return UserService | ||
| 21 | - * @author pengjch 2024311 11:32:35 | ||
| 22 | - */ | ||
| 23 | - public static function factory() | ||
| 24 | - { | ||
| 25 | - return parent::factory(); | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | - public function getName(): string | ||
| 29 | - { | ||
| 30 | - $register = new Consul(); | ||
| 31 | - try { | ||
| 32 | - $userID = 1; | ||
| 33 | - $client = \AukeySwrpc\Client::createBalancer('Class_Module', $register, \AukeySwrpc\Client::STRATEGY_WEIGHT); | ||
| 34 | - $result = $client->send(SyncRequest::create('ClassService_getUserClass', [$userID], $this->getTracerContext(__FUNCTION__))); | ||
| 35 | - } catch (RpcException $e) { | ||
| 36 | - return $e->getMessage() . PHP_EOL; | ||
| 37 | - } | ||
| 38 | - | ||
| 39 | - return 'user:wuzhc, class:' . $result; | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | - public function getAge(): int | ||
| 43 | - { | ||
| 44 | - return 30; | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | - public function getFavoriteFood($prefix) | ||
| 48 | - { | ||
| 49 | - return $prefix . '的我喜欢吃苹果'; | ||
| 50 | - } | ||
| 51 | -} |
-
请 注册 或 登录 后发表评论