qqq
This commit is contained in:
@@ -2,10 +2,9 @@
|
|||||||
|
|
||||||
namespace Kiri\Rpc;
|
namespace Kiri\Rpc;
|
||||||
|
|
||||||
use JetBrains\PhpStorm\ArrayShape;
|
|
||||||
use Kiri\Annotation\Inject;
|
|
||||||
use Kiri\Core\Json;
|
use Kiri\Core\Json;
|
||||||
use Kiri\Core\Number;
|
use Kiri\Core\Number;
|
||||||
|
use Kiri\Di\Inject\Container;
|
||||||
|
|
||||||
abstract class AbstractRpcClient
|
abstract class AbstractRpcClient
|
||||||
{
|
{
|
||||||
@@ -20,7 +19,7 @@ abstract class AbstractRpcClient
|
|||||||
/**
|
/**
|
||||||
* @var JsonRpcTransporterInterface
|
* @var JsonRpcTransporterInterface
|
||||||
*/
|
*/
|
||||||
#[Inject(JsonRpcTransporterInterface::class)]
|
#[Container(JsonRpcTransporterInterface::class)]
|
||||||
private JsonRpcTransporterInterface $transporter;
|
private JsonRpcTransporterInterface $transporter;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+65
-70
@@ -5,13 +5,13 @@ namespace Kiri\Rpc;
|
|||||||
use Exception;
|
use Exception;
|
||||||
use Kiri;
|
use Kiri;
|
||||||
use Kiri\Abstracts\Component;
|
use Kiri\Abstracts\Component;
|
||||||
use Kiri\Annotation\Inject;
|
|
||||||
use Kiri\Events\EventProvider;
|
use Kiri\Events\EventProvider;
|
||||||
use Kiri\Exception\ConfigException;
|
use Kiri\Exception\ConfigException;
|
||||||
use Kiri\Pool\Alias;
|
|
||||||
use Kiri\Pool\Pool;
|
use Kiri\Pool\Pool;
|
||||||
|
use Kiri\Di\Inject\Container;
|
||||||
use Kiri\Server\Events\OnBeforeShutdown;
|
use Kiri\Server\Events\OnBeforeShutdown;
|
||||||
use Swoole\Client;
|
use ReflectionException;
|
||||||
|
use Swoole\Coroutine\Client;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -20,86 +20,81 @@ use Swoole\Client;
|
|||||||
class ClientPool extends Component
|
class ClientPool extends Component
|
||||||
{
|
{
|
||||||
|
|
||||||
const POOL_NAME = 'rpc.client.pool';
|
public int $max;
|
||||||
|
|
||||||
use Alias;
|
|
||||||
|
|
||||||
|
|
||||||
public int $max;
|
public int $min;
|
||||||
|
|
||||||
|
|
||||||
public int $min;
|
private array $names = [];
|
||||||
|
|
||||||
|
|
||||||
public int $waite;
|
public function init(): void
|
||||||
|
{
|
||||||
|
on(OnBeforeShutdown::class, [$this, 'onBeforeShutdown']);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#[Inject(EventProvider::class)]
|
/**
|
||||||
public EventProvider $provider;
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function onBeforeShutdown(): void
|
||||||
|
{
|
||||||
|
$pool = Kiri::getDi()->get(Pool::class);
|
||||||
|
foreach ($this->names as $name) {
|
||||||
|
$pool->clean($name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private array $names = [];
|
/**
|
||||||
|
* @param $config
|
||||||
|
* @return resource
|
||||||
|
* @throws ConfigException
|
||||||
|
* @throws ReflectionException
|
||||||
|
*/
|
||||||
|
public function get($config): mixed
|
||||||
|
{
|
||||||
|
$coroutineName = $config['Address'] . '::' . $config['Port'];
|
||||||
|
|
||||||
|
if (!in_array($coroutineName, $this->names)) {
|
||||||
|
$this->names[] = $coroutineName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->getPool($config['Address'], $config['Port'])->get($coroutineName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public function init()
|
/**
|
||||||
{
|
* @param Client|\Swoole\Client $client
|
||||||
$this->provider->on(OnBeforeShutdown::class, [$this, 'onBeforeShutdown']);
|
* @param $host
|
||||||
}
|
* @param $port
|
||||||
|
* @throws ConfigException|ReflectionException
|
||||||
|
*/
|
||||||
|
public function push(Client|\Swoole\Client $client, $host, $port)
|
||||||
|
{
|
||||||
|
$this->getPool($host, $port)->push($host . '::' . $port, $client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return void
|
* @param $host
|
||||||
* @throws Exception
|
* @param $port
|
||||||
*/
|
* @return Pool
|
||||||
public function onBeforeShutdown(): void
|
* @throws ReflectionException
|
||||||
{
|
*/
|
||||||
foreach ($this->names as $name) {
|
public function getPool($host, $port): Pool
|
||||||
$this->getPool()->clean($name);
|
{
|
||||||
}
|
$pool = Kiri::getDi()->get(Pool::class);
|
||||||
}
|
$pool->initConnections($host . '::' . $port, 10, function () use ($host, $port) {
|
||||||
|
$client = stream_socket_client("tcp://$host:$port", $errCode, $errMessage, 3);
|
||||||
|
if ($client === false) {
|
||||||
/**
|
throw new Exception('Connect ' . $host . '::' . $port . ' fail');
|
||||||
* @param $config
|
}
|
||||||
* @param callable $callback
|
return $client;
|
||||||
* @return mixed
|
});
|
||||||
* @throws ConfigException
|
return $pool;
|
||||||
* @throws Exception
|
}
|
||||||
*/
|
|
||||||
public function get($config, callable $callback): mixed
|
|
||||||
{
|
|
||||||
$coroutineName = $this->name(self::POOL_NAME . '::' . $config['Address'] . '::' . $config['Port'], true);
|
|
||||||
|
|
||||||
$pool = $config['pool'] ?? ['min' => 1, 'max' => 100];
|
|
||||||
|
|
||||||
$this->names[] = $coroutineName;
|
|
||||||
|
|
||||||
return $this->getPool()->get($coroutineName, $callback, $pool['min'] ?? 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param \Swoole\Coroutine\Client|Client $client
|
|
||||||
* @param $host
|
|
||||||
* @param $port
|
|
||||||
* @throws ConfigException
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function push(\Swoole\Coroutine\Client|Client $client, $host, $port)
|
|
||||||
{
|
|
||||||
$coroutineName = $this->name(self::POOL_NAME . '::' . $host . '::' . $port, true);
|
|
||||||
|
|
||||||
$this->getPool()->push($coroutineName, $client);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Pool
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function getPool(): Pool
|
|
||||||
{
|
|
||||||
return Kiri::getDi()->get(Pool::class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,90 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
class Etcd
|
use Etcd\Client;
|
||||||
|
use GuzzleHttp\Exception\BadResponseException;
|
||||||
|
use Kiri\Abstracts\Component;
|
||||||
|
use Kiri\Core\Str;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Etcd extends Component
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
private Client $client;
|
||||||
|
|
||||||
|
|
||||||
|
private bool $isEnd = false;
|
||||||
|
|
||||||
|
|
||||||
|
private array $config = [];
|
||||||
|
|
||||||
|
|
||||||
|
private array|BadResponseException $grant;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function init(): void
|
||||||
|
{
|
||||||
|
$this->client = new Client('47.92.194.207:' . 2379, 'v3');
|
||||||
|
$this->grant = $this->client->grant(60);
|
||||||
|
if ($this->grant instanceof BadResponseException) {
|
||||||
|
throw new Exception($this->grant->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = 'center.service.' . gethostbyname(gethostname());
|
||||||
|
pcntl_signal(SIGINT, function () use ($key) {
|
||||||
|
$this->isEnd = true;
|
||||||
|
$this->client->del($key);
|
||||||
|
});
|
||||||
|
$this->client->put($key, json_encode([
|
||||||
|
'address' => gethostbyname(gethostname()) . ':10240',
|
||||||
|
'nodeId' => Str::rand(32)
|
||||||
|
]), ['lease' => (int)$this->grant["ID"]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function get(string $key): mixed
|
||||||
|
{
|
||||||
|
return $this->config[$key] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param mixed $value
|
||||||
|
* @return void
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function put(string $key, mixed $value): void
|
||||||
|
{
|
||||||
|
$result = $this->client->put($key, $value);
|
||||||
|
if ($result instanceof BadResponseException) {
|
||||||
|
throw new Exception($result->getMessage());
|
||||||
|
}
|
||||||
|
$this->config[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function waite(): void
|
||||||
|
{
|
||||||
|
while ($this->isEnd == false) {
|
||||||
|
$this->client->keepAlive((int)$this->grant["ID"]);
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
+12
-20
@@ -2,15 +2,9 @@
|
|||||||
|
|
||||||
namespace Kiri\Rpc;
|
namespace Kiri\Rpc;
|
||||||
|
|
||||||
use Kiri\Annotation\Inject;
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use Kiri\Message\Response;
|
use Kiri\Di\Inject\Container;
|
||||||
use Kiri\Message\Stream;
|
|
||||||
use Kiri\Abstracts\Config;
|
|
||||||
use Kiri\Exception\ConfigException;
|
use Kiri\Exception\ConfigException;
|
||||||
use Psr\Http\Message\RequestInterface;
|
|
||||||
use Psr\Http\Message\ResponseInterface;
|
|
||||||
use Swoole\Coroutine\Client;
|
|
||||||
|
|
||||||
class JsonRpcPoolTransporter implements JsonRpcTransporterInterface
|
class JsonRpcPoolTransporter implements JsonRpcTransporterInterface
|
||||||
{
|
{
|
||||||
@@ -19,16 +13,18 @@ class JsonRpcPoolTransporter implements JsonRpcTransporterInterface
|
|||||||
use TraitTransporter;
|
use TraitTransporter;
|
||||||
|
|
||||||
|
|
||||||
#[Inject(ClientPool::class)]
|
#[Container(ClientPool::class)]
|
||||||
public ClientPool $pool;
|
public ClientPool $pool;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $content
|
* @param string $content
|
||||||
* @param string $service
|
* @param string $service
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
* @throws ConfigException|RpcServiceException
|
* @throws ConfigException
|
||||||
*/
|
* @throws RpcServiceException
|
||||||
|
* @throws \ReflectionException
|
||||||
|
*/
|
||||||
public function push(string $content, string $service): string|bool
|
public function push(string $content, string $service): string|bool
|
||||||
{
|
{
|
||||||
$client = $this->get_consul($service)->getClient();
|
$client = $this->get_consul($service)->getClient();
|
||||||
@@ -42,16 +38,12 @@ class JsonRpcPoolTransporter implements JsonRpcTransporterInterface
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Client|\Swoole\Client
|
|
||||||
* @throws ConfigException
|
* @throws ConfigException
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private function getClient(): Client|\Swoole\Client
|
private function getClient()
|
||||||
{
|
{
|
||||||
$this->config['pool'] = Config::get('rpc.pool', ['max' => 10, 'min' => 1, 'waite' => 60]);
|
return $this->pool->get($this->config);
|
||||||
return $this->pool->get($this->config, function () {
|
|
||||||
return $this->newClient();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,8 @@
|
|||||||
|
|
||||||
namespace Kiri\Rpc;
|
namespace Kiri\Rpc;
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Kiri;
|
use Kiri;
|
||||||
use Kiri\Abstracts\Config;
|
|
||||||
use Kiri\Abstracts\Component;
|
use Kiri\Abstracts\Component;
|
||||||
use Kiri\Annotation\Inject;
|
|
||||||
use Kiri\Consul\Agent;
|
|
||||||
use Kiri\Consul\Health;
|
|
||||||
use Kiri\Message\Handler\Router;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,59 +12,4 @@ use Kiri\Message\Handler\Router;
|
|||||||
class RpcManager extends Component
|
class RpcManager extends Component
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Health
|
|
||||||
*/
|
|
||||||
#[Inject(Health::class)]
|
|
||||||
public Health $health;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $serviceName
|
|
||||||
* @return array|null
|
|
||||||
*/
|
|
||||||
public function getServices($serviceName): ?array
|
|
||||||
{
|
|
||||||
$lists = $this->health->setQuery('passing=true')->service($serviceName);
|
|
||||||
if ($lists->getStatusCode() != 200) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$body = json_decode($lists->getBody(), true);
|
|
||||||
if (empty($body)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return array_column($body, 'Service');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $name
|
|
||||||
* @param string $class
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function add(string $name, string $class): bool
|
|
||||||
{
|
|
||||||
Router::addServer('rpc', static function () use ($name, $class) {
|
|
||||||
Router::get($name, $class);
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $config
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function register(array $config): void
|
|
||||||
{
|
|
||||||
$agent = Kiri::getDi()->get(Agent::class);
|
|
||||||
$agent->checks->deregister($config['ID']);
|
|
||||||
$agent->service->deregister($config['ID']);
|
|
||||||
$data = $agent->service->register($config);
|
|
||||||
if ($data->getStatusCode() != 200) {
|
|
||||||
$this->logger->error($data->getBody());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ namespace Kiri\Rpc;
|
|||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use JetBrains\PhpStorm\ArrayShape;
|
use JetBrains\PhpStorm\ArrayShape;
|
||||||
use Kiri\Annotation\Inject;
|
|
||||||
use Kiri\Di\Context;
|
use Kiri\Di\Context;
|
||||||
|
use Kiri\Di\Inject\Container;
|
||||||
use Swoole\Client;
|
use Swoole\Client;
|
||||||
use Swoole\Coroutine;
|
use Swoole\Coroutine;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ trait TraitTransporter
|
|||||||
/**
|
/**
|
||||||
* @var RpcManager
|
* @var RpcManager
|
||||||
*/
|
*/
|
||||||
#[Inject(RpcManager::class)]
|
#[Container(RpcManager::class)]
|
||||||
public RpcManager $manager;
|
public RpcManager $manager;
|
||||||
|
|
||||||
|
|
||||||
@@ -24,13 +24,16 @@ trait TraitTransporter
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Client|Coroutine\Client $client
|
* @param resource $client
|
||||||
* @param $content
|
* @param $content
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
private function request(Client|Coroutine\Client $client, $content): string|bool
|
private function request(mixed $client, $content): string|bool
|
||||||
{
|
{
|
||||||
$client->send($content);
|
socket_write($client, $content, mb_strlen($content));
|
||||||
|
|
||||||
|
socket_read($client, 1024);
|
||||||
|
|
||||||
return $client->recv();
|
return $client->recv();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-3
@@ -10,13 +10,21 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.0",
|
"php": ">=8.0",
|
||||||
"ext-json": "*"
|
"ext-json": "*",
|
||||||
|
"start-point/etcd-php": "^1.1"
|
||||||
|
},
|
||||||
|
"replace": {
|
||||||
|
"symfony/polyfill-apcu": "*",
|
||||||
|
"symfony/polyfill-php80": "*",
|
||||||
|
"symfony/polyfill-mbstring": "*",
|
||||||
|
"symfony/polyfill-ctype": "*",
|
||||||
|
"symfony/polyfill-php73": "*",
|
||||||
|
"symfony/polyfill-php72": "*",
|
||||||
|
"symfony/polyfill-php81": "*"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Kiri\\Rpc\\": "./"
|
"Kiri\\Rpc\\": "./"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user