2021-10-28 10:52:09 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Kiri\Rpc;
|
|
|
|
|
|
2021-12-02 15:48:32 +08:00
|
|
|
use Kiri\Abstracts\Config;
|
2021-12-02 14:06:57 +08:00
|
|
|
use Kiri\Consul\Agent;
|
2021-12-02 15:25:41 +08:00
|
|
|
use Kiri\Consul\Health;
|
2021-10-28 15:14:21 +08:00
|
|
|
use Kiri\Kiri;
|
|
|
|
|
use ReflectionException;
|
2021-12-02 15:48:32 +08:00
|
|
|
use Swoole\Table;
|
2021-10-28 15:14:21 +08:00
|
|
|
|
2021-10-28 10:52:09 +08:00
|
|
|
class RpcManager
|
|
|
|
|
{
|
|
|
|
|
|
2021-11-30 14:44:34 +08:00
|
|
|
|
|
|
|
|
/**
|
2021-11-30 14:44:51 +08:00
|
|
|
* @var array
|
2021-11-30 14:44:34 +08:00
|
|
|
*/
|
2021-12-02 14:06:57 +08:00
|
|
|
private array $_rpc = [];
|
2021-10-28 15:14:21 +08:00
|
|
|
|
2021-10-28 10:52:09 +08:00
|
|
|
|
2021-12-02 15:48:32 +08:00
|
|
|
private Table $table;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function tableInit()
|
|
|
|
|
{
|
|
|
|
|
$this->table = new Table((int)Config::get('rpc.total', 10));
|
|
|
|
|
$this->table->column('content', Table::TYPE_STRING);
|
|
|
|
|
$this->table->create();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-12-02 15:25:41 +08:00
|
|
|
/**
|
|
|
|
|
* @param $serviceName
|
2021-12-02 15:32:54 +08:00
|
|
|
* @return void
|
2021-12-02 15:25:41 +08:00
|
|
|
* @throws ReflectionException
|
2021-12-02 15:32:54 +08:00
|
|
|
* @throws \Exception
|
2021-12-02 15:25:41 +08:00
|
|
|
*/
|
2021-12-02 15:32:54 +08:00
|
|
|
public function async($serviceName): void
|
2021-12-02 15:25:41 +08:00
|
|
|
{
|
|
|
|
|
$lists = Kiri::getDi()->get(Health::class)->setQuery('passing=true')->service($serviceName);
|
|
|
|
|
if ($lists->getStatusCode() != 200) {
|
2021-12-02 15:32:54 +08:00
|
|
|
return;
|
2021-12-02 15:25:41 +08:00
|
|
|
}
|
|
|
|
|
$body = json_decode($lists->getBody(), true);
|
2021-12-02 15:32:54 +08:00
|
|
|
if (!empty($body) && is_array($body)) {
|
2021-12-02 15:48:32 +08:00
|
|
|
$this->table->set($serviceName, ['content' => json_encode(array_column($body, 'Service'))]);
|
2021-12-02 15:32:54 +08:00
|
|
|
} else {
|
2021-12-02 15:48:32 +08:00
|
|
|
$this->table->set($serviceName, ['content' => json_encode([])]);
|
2021-12-02 15:25:41 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws ReflectionException
|
|
|
|
|
*/
|
|
|
|
|
public function tick(): void
|
|
|
|
|
{
|
|
|
|
|
foreach ($this->_rpc as $name => $list) {
|
|
|
|
|
$this->async($name);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param $serviceName
|
|
|
|
|
* @return array
|
2021-12-02 15:32:54 +08:00
|
|
|
* @throws \Exception
|
2021-12-02 15:25:41 +08:00
|
|
|
*/
|
|
|
|
|
public function getServices($serviceName): array
|
|
|
|
|
{
|
2021-12-02 15:40:45 +08:00
|
|
|
$file = storage('.rpc.clients.' . md5($serviceName), 'rpc');
|
2021-12-02 15:48:32 +08:00
|
|
|
if (!$this->table->exist($file)) {
|
2021-12-02 15:32:54 +08:00
|
|
|
return [];
|
|
|
|
|
}
|
2021-12-02 15:48:32 +08:00
|
|
|
$content = json_decode($this->table->get($serviceName), true);
|
2021-12-02 15:32:54 +08:00
|
|
|
if (empty($content) || !is_array($content)) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
return $content;
|
2021-12-02 15:25:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-10-28 15:14:21 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @param string $class
|
2021-12-02 14:06:57 +08:00
|
|
|
* @param array $serviceConfig
|
2021-10-28 15:14:21 +08:00
|
|
|
* @return bool
|
|
|
|
|
* @throws ReflectionException
|
|
|
|
|
*/
|
2021-12-02 14:06:57 +08:00
|
|
|
public function add(string $name, string $class, array $serviceConfig): bool
|
2021-10-28 10:52:09 +08:00
|
|
|
{
|
2021-10-28 15:14:21 +08:00
|
|
|
$methods = Kiri::getDi()->getReflect($class);
|
|
|
|
|
$lists = $methods->getMethods(\ReflectionMethod::IS_PUBLIC);
|
|
|
|
|
|
2021-12-02 14:13:44 +08:00
|
|
|
if (!isset($this->_rpc[$name])) {
|
|
|
|
|
$this->_rpc[$name] = ['methods' => [], 'id' => $serviceConfig['ID'], 'config' => $serviceConfig];
|
|
|
|
|
}
|
2021-10-28 10:52:09 +08:00
|
|
|
|
2021-10-28 15:14:21 +08:00
|
|
|
foreach ($lists as $reflection) {
|
2021-10-28 15:39:34 +08:00
|
|
|
$methodName = $reflection->getName();
|
2021-10-28 15:14:21 +08:00
|
|
|
|
2021-12-02 14:06:57 +08:00
|
|
|
$this->_rpc[$name]['methods'][$methodName] = [[$class, $methodName], null];
|
2021-10-28 15:14:21 +08:00
|
|
|
}
|
|
|
|
|
return true;
|
2021-10-28 10:52:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-11-30 14:44:34 +08:00
|
|
|
/**
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
2021-12-02 14:06:57 +08:00
|
|
|
public function doneList(): array
|
2021-10-29 18:06:04 +08:00
|
|
|
{
|
|
|
|
|
$array = [];
|
2021-12-02 14:06:57 +08:00
|
|
|
foreach ($this->_rpc as $list) {
|
|
|
|
|
$array[] = $list;
|
2021-10-29 18:06:04 +08:00
|
|
|
}
|
|
|
|
|
return $array;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-12-02 14:06:57 +08:00
|
|
|
/**
|
|
|
|
|
* @throws ReflectionException
|
|
|
|
|
*/
|
|
|
|
|
public function register()
|
|
|
|
|
{
|
|
|
|
|
$agent = Kiri::getDi()->get(Agent::class);
|
|
|
|
|
foreach ($this->_rpc as $list) {
|
|
|
|
|
$data = $agent->service->register($list['config']);
|
|
|
|
|
if ($data->getStatusCode() != 200) {
|
2021-12-02 14:40:10 +08:00
|
|
|
exit($data->getBody());
|
2021-12-02 14:06:57 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-10-28 15:14:21 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $name
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @return mixed
|
|
|
|
|
*/
|
2021-12-02 14:06:57 +08:00
|
|
|
public function get(string $name, string $method): array
|
2021-10-28 10:52:09 +08:00
|
|
|
{
|
2021-12-02 14:06:57 +08:00
|
|
|
return $this->_rpc[$name]['methods'][$method] ?? [null, null];
|
2021-10-28 10:52:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|