Files
kiri-core/Rpc/Client.php
T

141 lines
2.9 KiB
PHP
Raw Normal View History

2021-03-23 02:29:48 +08:00
<?php
namespace Rpc;
2021-03-23 10:30:14 +08:00
use Exception;
2021-03-23 02:29:48 +08:00
use Snowflake\Abstracts\Component;
2021-03-29 17:47:13 +08:00
use Snowflake\Channel;
2021-03-23 18:05:16 +08:00
use Snowflake\Core\Json;
2021-03-29 17:47:13 +08:00
use Snowflake\Snowflake;
2021-03-23 02:29:48 +08:00
use Swoole\Coroutine\Client as CClient;
/**
* Class Client
* @package Rpc
*/
class Client extends Component
{
2021-03-23 16:42:57 +08:00
public array $config = [];
2021-03-23 02:29:48 +08:00
2021-03-23 16:42:57 +08:00
public string $service = '';
2021-03-23 02:29:48 +08:00
2021-03-23 16:50:59 +08:00
private ?CClient $client = null;
2021-03-23 02:29:48 +08:00
2021-03-23 16:14:05 +08:00
/**
* @param string $cmd
2021-03-23 10:30:14 +08:00
* @param array $param
* @return mixed
* @throws Exception
*/
2021-03-23 16:14:05 +08:00
public function dispatch(string $cmd, array $param): mixed
{
2021-03-23 16:50:59 +08:00
if (empty($this->config)) {
2021-03-23 16:56:05 +08:00
return $this->addError('Related service not found(404)');
2021-03-23 16:14:05 +08:00
}
if (!($this->client instanceof CClient)) {
$this->client = $this->getClient();
}
2021-03-29 18:41:51 +08:00
if (!$this->client->isConnected() && !$this->connect()) {
2021-03-24 18:47:41 +08:00
return false;
2021-03-23 16:14:05 +08:00
}
2021-04-30 15:19:34 +08:00
$isSend = $this->client->send(implode("\n", [$cmd, '', serialize($param)]));
2021-03-23 16:14:05 +08:00
if ($isSend === false) {
2021-03-23 16:56:05 +08:00
return $this->addError($this->client->errMsg . '(' . $this->client->errCode . ')');
2021-03-23 16:14:05 +08:00
}
2021-05-11 11:10:38 +08:00
defer(fn() => $this->clientRecover());
2021-03-23 18:23:45 +08:00
if (is_bool($unpack = Json::decode($this->client->recv()))) {
2021-03-29 18:45:05 +08:00
$unpack = $this->addError('Service return data format error(500)');
2021-03-23 16:56:53 +08:00
}
return $unpack;
2021-03-23 16:14:05 +08:00
}
2021-03-29 18:41:51 +08:00
/**
2021-03-29 18:49:43 +08:00
* @return Client
2021-03-29 18:41:51 +08:00
* @throws Exception
*/
2021-03-29 18:45:05 +08:00
public function clientRecover(): static
2021-03-29 18:41:51 +08:00
{
2021-03-29 18:49:43 +08:00
$host = $this->config['host'] ?? '127.0.0.1';
$port = $this->config['port'] ?? 0;
if ($port < 0) {
return $this;
}
2021-03-29 18:41:51 +08:00
/** @var Channel $channel */
$channel = Snowflake::app()->get('channel');
2021-03-29 18:49:43 +08:00
$channel->push($this->client, $host . $port . CClient::class);
2021-03-29 18:41:51 +08:00
$this->client = null;
return $this;
}
2021-03-24 18:47:41 +08:00
/**
* @return bool
* @throws Exception
*/
private function connect(): bool
{
$host = $this->config['host'] ?? '127.0.0.1';
if (!isset($this->config['port'])) {
return $this->addError('Related service not have port(404)');
}
$timeout = $this->config['timeout'] ?? 0.2;
if (!$this->client->connect($host, $this->config['port'], $timeout)) {
return $this->addError($this->client->errMsg . '(' . $this->client->errCode . ')');
}
return true;
}
2021-03-23 16:52:45 +08:00
/**
* 断开链接
*/
public function close()
{
if (!$this->client || !$this->client->isConnected()) {
return;
}
$this->client->close();
}
2021-03-23 16:14:05 +08:00
/**
* @return mixed
* @throws Exception
*/
public function getClient(): CClient
{
2021-03-29 17:47:13 +08:00
/** @var Channel $channel */
$channel = Snowflake::app()->get('channel');
2021-03-29 18:49:43 +08:00
$host = $this->config['host'] ?? '127.0.0.1';
$port = $this->config['port'] ?? 0;
if ($port < 0) {
throw new Exception('Related service not have port(404)');
}
return $channel->pop($host . $port . CClient::class, function () {
2021-03-23 16:48:10 +08:00
$client = new CClient($this->config['mode'] ?? SWOOLE_SOCK_TCP);
2021-03-23 16:14:05 +08:00
$client->set([
'timeout' => 0.5,
'connect_timeout' => 1.0,
'write_timeout' => 10.0,
'read_timeout' => 0.5,
'open_tcp_keepalive' => true,
]);
2021-03-23 16:48:10 +08:00
return $client;
2021-03-23 16:14:05 +08:00
});
}
2021-03-23 02:29:48 +08:00
}