2021-10-26 18:58:09 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Kiri\Rpc;
|
|
|
|
|
|
|
|
|
|
|
2021-10-28 10:20:53 +08:00
|
|
|
use Exception;
|
2021-10-28 18:24:46 +08:00
|
|
|
use Http\Message\ServerRequest;
|
|
|
|
|
use Http\Message\Stream;
|
2021-11-01 14:13:26 +08:00
|
|
|
use Kiri\Consul\Agent;
|
2021-10-28 15:40:50 +08:00
|
|
|
use Kiri\Core\Number;
|
2021-10-28 18:24:46 +08:00
|
|
|
use Kiri\Kiri;
|
2021-10-26 18:58:09 +08:00
|
|
|
use Kiri\Pool\Pool;
|
2021-10-28 18:24:46 +08:00
|
|
|
use Psr\Http\Client\ClientExceptionInterface;
|
|
|
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
|
use Psr\Http\Message\ServerRequestInterface;
|
2021-10-26 18:58:09 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
*/
|
2021-10-28 10:55:28 +08:00
|
|
|
abstract class JsonRpcConsumers implements OnRpcConsumerInterface
|
2021-10-26 18:58:09 +08:00
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @var Pool
|
|
|
|
|
*/
|
|
|
|
|
public Pool $pool;
|
|
|
|
|
|
|
|
|
|
|
2021-10-28 17:31:18 +08:00
|
|
|
protected string $name = '';
|
|
|
|
|
|
|
|
|
|
|
2021-10-26 18:58:09 +08:00
|
|
|
/**
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @param mixed $data
|
|
|
|
|
* @param string $version
|
2021-10-28 10:20:53 +08:00
|
|
|
* @throws Exception
|
2021-10-28 18:24:46 +08:00
|
|
|
* @throws ClientExceptionInterface
|
2021-10-26 18:58:09 +08:00
|
|
|
*/
|
2021-10-28 17:31:18 +08:00
|
|
|
public function notify(string $method, mixed $data, string $version = '2.0'): void
|
2021-10-26 18:58:09 +08:00
|
|
|
{
|
2021-10-28 17:31:18 +08:00
|
|
|
$config = $this->get_consul($this->name);
|
2021-10-28 18:24:46 +08:00
|
|
|
$transporter = Kiri::getDi()->get(RpcClientInterface::class);
|
|
|
|
|
$transporter->withConfig($config)->sendRequest(
|
|
|
|
|
$this->requestBody([
|
|
|
|
|
'jsonrpc' => $version,
|
|
|
|
|
'service' => $this->name,
|
|
|
|
|
'method' => $method,
|
|
|
|
|
'params' => $data,
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param array $data
|
|
|
|
|
* @return ServerRequestInterface
|
2021-12-02 14:06:57 +08:00
|
|
|
* @throws \ReflectionException
|
2021-10-28 18:24:46 +08:00
|
|
|
*/
|
|
|
|
|
private function requestBody(array $data): ServerRequestInterface
|
|
|
|
|
{
|
|
|
|
|
$server = Kiri::getDi()->get(ServerRequest::class);
|
|
|
|
|
return $server->withBody(new Stream(json_encode($data)));
|
2021-10-26 18:58:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param string $method
|
|
|
|
|
* @param mixed $data
|
|
|
|
|
* @param string $version
|
|
|
|
|
* @param string $id
|
|
|
|
|
* @return mixed
|
2021-10-28 10:20:53 +08:00
|
|
|
* @throws Exception
|
2021-10-28 18:24:46 +08:00
|
|
|
* @throws ClientExceptionInterface
|
2021-10-26 18:58:09 +08:00
|
|
|
*/
|
2021-10-28 18:24:46 +08:00
|
|
|
public function get(string $method, mixed $data, string $version = '2.0', string $id = ''): ResponseInterface
|
2021-10-26 18:58:09 +08:00
|
|
|
{
|
2021-10-28 15:40:50 +08:00
|
|
|
if (empty($id)) $id = Number::create(time());
|
|
|
|
|
|
2021-10-28 18:24:46 +08:00
|
|
|
$config = $this->get_consul($this->name);
|
|
|
|
|
$transporter = Kiri::getDi()->get(RpcClientInterface::class);
|
|
|
|
|
return $transporter->withConfig($config)->sendRequest(
|
|
|
|
|
$this->requestBody([
|
|
|
|
|
'jsonrpc' => $version,
|
|
|
|
|
'service' => $this->name,
|
|
|
|
|
'method' => $method,
|
|
|
|
|
'params' => $data,
|
|
|
|
|
'id' => $id
|
|
|
|
|
])
|
|
|
|
|
);
|
2021-10-28 10:20:53 +08:00
|
|
|
}
|
|
|
|
|
|
2021-10-26 18:58:09 +08:00
|
|
|
|
2021-10-28 10:20:53 +08:00
|
|
|
/**
|
|
|
|
|
* @param array $data
|
|
|
|
|
* @return mixed
|
2021-10-28 18:24:46 +08:00
|
|
|
* @throws ClientExceptionInterface
|
2021-10-28 10:20:53 +08:00
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2021-10-28 18:24:46 +08:00
|
|
|
public function batch(array $data): mixed
|
2021-10-28 10:20:53 +08:00
|
|
|
{
|
2021-10-28 18:24:46 +08:00
|
|
|
$config = $this->get_consul($this->name);
|
|
|
|
|
$transporter = Kiri::getDi()->get(RpcClientInterface::class);
|
|
|
|
|
return $transporter->withConfig($config)->sendRequest(
|
|
|
|
|
$this->requestBody($data)
|
|
|
|
|
);
|
2021-10-26 18:58:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2021-10-28 10:20:53 +08:00
|
|
|
/**
|
|
|
|
|
* @param $service
|
|
|
|
|
* @return array
|
2021-10-28 17:34:10 +08:00
|
|
|
* @throws Exception
|
2021-10-28 10:20:53 +08:00
|
|
|
*/
|
|
|
|
|
private function get_consul($service): array
|
2021-10-26 18:58:09 +08:00
|
|
|
{
|
2021-10-28 17:34:10 +08:00
|
|
|
if (empty($service)) {
|
|
|
|
|
throw new Exception('You need set rpc service name if used.');
|
|
|
|
|
}
|
2021-11-01 14:13:26 +08:00
|
|
|
$sf = Kiri::getDi()->get(Agent::class);
|
|
|
|
|
|
2021-11-01 14:16:36 +08:00
|
|
|
$response = $sf->service->setQuery('filter=Service == ' . $service)->list();
|
2021-11-01 14:13:26 +08:00
|
|
|
if ($response->getStatusCode() != 200 || $response->getBody()->getSize() <= 2) {
|
|
|
|
|
throw new Exception('No microservices found [' . $service . '].');
|
|
|
|
|
}
|
|
|
|
|
$array = [];
|
|
|
|
|
|
|
|
|
|
$content = json_decode($response->getBody()->getContents(), true);
|
|
|
|
|
foreach ($content as $value) {
|
|
|
|
|
$array[] = ['id' => $value['ID'], 'Weights' => $value['Weights']['Passing']];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (count($array) < 2) {
|
|
|
|
|
$luck = $array[0];
|
|
|
|
|
} else {
|
|
|
|
|
$luck = Luckdraw::luck($array, 'Weights');
|
|
|
|
|
}
|
|
|
|
|
return ['Address' => $luck['Address'], 'Port' => $luck['Port']];
|
2021-10-26 18:58:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|