This commit is contained in:
2021-08-11 19:14:26 +08:00
parent 3ce7315250
commit 39af292171
21 changed files with 533 additions and 392 deletions
-44
View File
@@ -1,44 +0,0 @@
<?php
namespace Annotation\Rpc;
use Annotation\Attribute;
use Exception;
use Kiri\Kiri;
/**
* Class Consumer
* @package Annotation\Rpc
*/
#[\Attribute(\Attribute::TARGET_METHOD)] class Consumer extends Attribute
{
/**
* Consumer constructor.
* @param string $cmd
*/
public function __construct(public string $cmd)
{
}
/**
* @param mixed $class
* @param mixed $method
* @return bool
* @throws Exception
*/
public function execute(mixed $class, mixed $method = ''): bool
{
$rpc = Kiri::app()->getRpc();
$rpc->addConsumer($this->cmd, [$class, $method]);
return true; // TODO: Change the autogenerated stub
}
}
+9 -8
View File
@@ -3,6 +3,7 @@ declare(strict_types=1);
namespace Console;
use Exception;
use ReflectionException;
use Kiri\Abstracts\BaseObject;
use Kiri\Abstracts\TraitApplication;
@@ -44,13 +45,13 @@ abstract class Command extends BaseObject implements CommandInterface
}
/**
* @param $name
* @return mixed
* @throws ComponentException
* @throws NotFindClassException
* @throws ReflectionException
*/
/**
* @param $name
* @return mixed
* @throws NotFindClassException
* @throws ReflectionException
* @throws Exception
*/
public function __get($name): mixed
{
if ($this->has($name)) {
@@ -63,6 +64,7 @@ abstract class Command extends BaseObject implements CommandInterface
/**
* @param $name
* @return bool
* @throws
*/
private function has($name): bool
{
@@ -74,7 +76,6 @@ abstract class Command extends BaseObject implements CommandInterface
* @param $name
* @return mixed
* @throws ReflectionException
* @throws ComponentException
* @throws NotFindClassException
*/
private function get($name): mixed
+35 -1
View File
@@ -16,8 +16,9 @@ use HttpServer\Http\Formatter\HtmlFormatter;
use HttpServer\Http\Formatter\JsonFormatter;
use HttpServer\Http\Formatter\XmlFormatter;
use HttpServer\IInterface\IFormatter;
use Server\ResponseInterface;
use Kiri\Exception\NotFindClassException;
use Server\ResponseInterface;
use Server\ServerManager;
use Swoole\Http\Response as SResponse;
/**
@@ -53,6 +54,29 @@ class Response extends HttpService implements ResponseInterface
];
public int $fd = 0;
private int $clientId = 0;
private int $reactorId = 0;
/**
* @param int $int
* @param int $reID
*/
public function setClientId(int $int, int $reID)
{
$this->clientId = $int;
$this->reactorId = $reID;
}
/**
* @return mixed
*/
public function getClientInfo(): mixed
{
$server = ServerManager::getContext()->getServer();
return $server->getClientInfo($this->clientId, $this->reactorId);
}
/**
@@ -64,6 +88,15 @@ class Response extends HttpService implements ResponseInterface
}
/**
* @return int
*/
public function getClientId(): int
{
return $this->clientId;
}
/**
* @param $format
* @return $this
@@ -117,6 +150,7 @@ class Response extends HttpService implements ResponseInterface
/**
* @param string $path
* @param bool $isChunk
* @param int $offset
* @param int $limit
* @return $this|Response
* @throws Exception
-1
View File
@@ -14,7 +14,6 @@ use HttpServer\IInterface\Middleware;
use HttpServer\IInterface\RouterInterface;
use JetBrains\PhpStorm\Pure;
use ReflectionException;
use Rpc\Actuator;
use Server\RequestInterface;
use Kiri\Abstracts\Config;
use Kiri\Exception\ConfigException;
-45
View File
@@ -1,45 +0,0 @@
<?php
namespace Rpc;
use Exception;
use HttpServer\Route\Router;
use Kiri\Kiri;
/**
* Class Actuator
* @package Rpc
*/
class Actuator
{
private Router $router;
/**
* Actuator constructor.
* @param int $port
* @throws Exception
*/
public function __construct(public int $port)
{
$this->router = Kiri::getApp('router');
}
/**
* @param string $path
* @param string|callable $callback
* @throws Exception
*/
public function addListener(string $path, string|callable $callback): void
{
$this->router->addRoute('rpc/p' . $this->port . '/' . ltrim($path, '/'), $callback);
}
}
-188
View File
@@ -1,188 +0,0 @@
<?php
namespace Rpc;
use Exception;
use JetBrains\PhpStorm\ArrayShape;
use Kiri\Abstracts\Component;
use Kiri\Kiri;
/**
* Class Producer
* @package Rpc
*/
class Producer extends Component
{
private static array $producers = [];
private static array $classAlias = [];
private static array $consumers = [];
private static array $cods = [];
/**
* @param string $name
* @param array $handler
* @param array $node
*/
public function addProducer(string $name, array $handler, array $node)
{
static::$classAlias[$handler[0]::class] = $name;
static::$consumers[$name] = $handler[0];
static::$producers[$name] = $node;
}
/**
* @param string $cmd
* @param array $handler
*/
public function addConsumer(string $cmd, array $handler)
{
$class = $handler[0]::class;
if (!isset(static::$classAlias[$class])) {
return;
}
$name = static::$classAlias[$class];
static::$cods[$name . '.' . $cmd] = $handler;
}
/**
* @param $cmd
* @param mixed ...$params
* @return mixed
*/
public function dispatch($cmd, mixed ...$params): mixed
{
$handler = static::$cods[$cmd] ?? null;
if (empty($handler)) {
return false;
}
return call_user_func($handler, ...$params);
}
/**
* @param $name
* @return mixed
* @throws Exception
*/
public function get($name): mixed
{
if (!isset(static::$consumers[$name])) {
throw new Exception('Unknown rpc client.');
}
return static::$consumers[$name];
}
/**
* @return array
*/
public function getService(): array
{
$array = [];
foreach (array_keys(static::$cods) as $key) {
$explode = explode('.', $key);
$prefix = array_shift($explode);
$explode = implode('.', $explode);
if (!isset($array[$prefix])) {
$array[$prefix] = [];
}
$array[$prefix][] = $explode;
}
return $array;
}
/**
* @param string $name
* @param string|null $host
* @return mixed
* @throws Exception
*/
public function getClient(string $name, string $host = null): Client
{
$producer = static::$producers[$name] ?? null;
if ($producer === null) {
throw new Exception('Unknown rpc client config.');
}
if (!empty($host)) {
$producer['host'] = $host;
} else if (!isset($producer['host'])) {
$producer['host'] = Kiri::localhost();
}
$producerName = $this->getName($name, $producer);
$snowflake = Kiri::app();
if (!$snowflake->has($producerName)) {
return $snowflake->set($producerName, $this->definer($name, $producer));
} else {
return $snowflake->get($producerName);
}
}
/**
* @param string $name
* @param string|null $host
* @return Client
* @throws Exception
*/
public function consumer(string $name, string $host = null): Client
{
return $this->getClient($name, $host);
}
/**
* @param $name
* @param $producer
* @return array
*/
#[ArrayShape(['class' => "string", 'service' => "", 'config' => ""])]
private function definer($name, $producer): array
{
return ['class' => Client::class, 'service' => $name, 'config' => $producer];
}
/**
* @param $name
* @return Client|bool
* @throws Exception
*/
public function __get($name): Client|bool
{
return $this->get($name); // TODO: Change the autogenerated stub
}
/**
* @param $name
* @param $config
* @return string
*/
private function getName($name, $config): string
{
return 'rpc.client.' . $name . '.' . $config['host'];
}
}
-42
View File
@@ -1,42 +0,0 @@
<?php
use HttpServer\Server;
use Kiri\Kiri;
/** @var \HttpServer\Route\Router $router */
$router = Kiri::getApp('router');
$router->addRpcService(9527, function (\Rpc\Actuator $actuator) {
$actuator->addListener('', '');
$actuator->addListener('', '');
});
return [
'rpc' => [
'type' => Server::TCP,
'host' => '0.0.0.0',
'mode' => SWOOLE_SOCK_TCP,
'port' => 5377,
'setting' => [
'open_tcp_keepalive' => true,
'tcp_keepidle' => 30,
'tcp_keepinterval' => 10,
'tcp_keepcount' => 10,
'open_http_protocol' => false,
'open_websocket_protocol' => false,
],
'events' => [
Server::SERVER_ON_CONNECT => [],
Server::SERVER_ON_CLOSE => [],
],
'registry' => [
'protocol' => 'consul',
'address' => [
'host' => '47.14.25.45',
'port' => 5527,
'path' => ''
],
],
]
];
+25 -4
View File
@@ -4,9 +4,11 @@ namespace Server\Constrict;
use Exception;
use HttpServer\Http\Formatter\FileFormatter;
use HttpServer\IInterface\IFormatter;
use Kiri\Exception\NotFindClassException;
use ReflectionException;
use Server\ResponseInterface;
use Kiri\Exception\NotFindClassException;
use Swoole\Server;
/**
@@ -17,15 +19,19 @@ class ResponseEmitter
/**
* @param \Swoole\Http\Response|\Swoole\Http2\Response $response
* @param \Swoole\Http\Response|\Swoole\Http2\Response|Server $response
* @param ResponseInterface $emitter
* @throws ReflectionException
* @throws NotFindClassException
* @throws ReflectionException
* @throws Exception
*/
public function sender(\Swoole\Http\Response|\Swoole\Http2\Response $response, ResponseInterface $emitter)
public function sender(\Swoole\Http\Response|\Swoole\Http2\Response|Server $response, ResponseInterface $emitter)
{
$content = $emitter->configure($response)->getContent();
if ($response instanceof Server) {
$this->sendTcpData($response, $emitter, $content);
return;
}
if ($content instanceof FileFormatter) {
$this->download($content->getData(), $response);
} else {
@@ -35,6 +41,21 @@ class ResponseEmitter
}
/**
* @param Server $response
* @param ResponseInterface $emitter
* @param IFormatter $formatter
*/
private function sendTcpData(Server $response, ResponseInterface $emitter, IFormatter $formatter)
{
if ($formatter instanceof FileFormatter) {
$response->sendfile($emitter->getClientId(), $formatter->getData());
} else {
$response->send($emitter->getClientId(), $formatter->getData());
}
}
const IMAGES = [
'png' => 'image/png',
'jpeg' => 'image/jpeg',
+6 -2
View File
@@ -112,11 +112,15 @@ trait Attributes
/**
* @param ReflectionClass $class
* @param ReflectionClass|string $class
* @return array
* @throws \ReflectionException
*/
#[Pure] public function getMethods(ReflectionClass $class): array
public function getMethods(ReflectionClass|string $class): array
{
if (is_string($class)) {
$class = $this->getReflect($class);
}
return $this->_classMethod[$class->getName()] ?? [];
}
+26
View File
@@ -0,0 +1,26 @@
{
"name": "game-worker/rpc-server",
"description": "db",
"authors": [
{
"name": "XiangLin",
"email": "as2252258@163.com"
}
],
"license": "MIT",
"require": {
"php": ">=8.0",
"ext-json": "*",
"ext-pdo": "*",
"game-worker/snowflake": "dev-master",
"game-worker/validator": "dev-master"
},
"autoload": {
"psr-4": {
"Rpc\\": "src/"
}
},
"require-dev": {
"kwn/php-rdkafka-stubs": "^2.0"
}
}
@@ -0,0 +1,48 @@
<?php
namespace Annotation\Rpc;
use Annotation\Attribute;
use Exception;
use Kiri\Kiri;
/**
* Class RpcClient
* @package Annotation\Rpc
*/
#[\Attribute(\Attribute::TARGET_CLASS)] class RpcConsumer extends Attribute
{
/**
* RpcClient constructor.
* @param string $package
* @param string $method
* @param int $timeout
* @param int $mode
*/
public function __construct(
public string $package,
public string $method,
public int $timeout,
public int $mode
)
{
}
/**
* @param mixed $class
* @param mixed $method
* @return bool
* @throws Exception
*/
public function execute(mixed $class, mixed $method = ''): bool
{
return true;
}
}
+57
View File
@@ -0,0 +1,57 @@
<?php
namespace Rpc\Annotation;
use Annotation\Attribute;
use Exception;
use HttpServer\Route\Router;
use JetBrains\PhpStorm\Pure;
use Kiri\Kiri;
/**
* Class RpcProducer
* @package Annotation\Route
*/
#[\Attribute(\Attribute::TARGET_CLASS)] class RpcService extends Attribute
{
const PROTOCOL_JSON = 'json';
const PROTOCOL_SERIALIZE = 'serialize';
/**
* Route constructor.
* @param string $package
* @param string $protocol
* @param string $server
* @param string $version
*/
#[Pure] public function __construct(public string $package, public string $protocol = self::PROTOCOL_SERIALIZE, public string $server = 'json-rpc',
public string $version = 'v1.0')
{
}
/**
* @param mixed $class
* @param mixed|null $method
* @return Router
* @throws Exception
*/
public function execute(mixed $class, mixed $method = null): Router
{
// TODO: Implement setHandler() method.
$router = Kiri::app()->getRouter();
$methods = Kiri::getDi()->getMethods($class::class);
foreach ($methods as $method => $reflectionMethod) {
$router->addRoute(':rpc/' . $this->package . '/' . $method . '/' . $this->version, [$class, $method], $this->server);
}
return $router;
}
}
+6 -23
View File
@@ -6,7 +6,6 @@ namespace Rpc;
use Exception;
use Kiri\Abstracts\Component;
use Kiri\Channel;
use Kiri\Core\Json;
use Swoole\Coroutine\Client as CClient;
@@ -28,12 +27,13 @@ class Client extends Component
/**
* @param string $cmd
* @param string $package
* @param string $method
* @param array $param
* @return mixed
* @throws Exception
*/
public function dispatch(string $cmd, array $param): mixed
public function dispatch(string $package, string $method, array $param): mixed
{
if (empty($this->config)) {
return $this->addError('Related service not found(404)');
@@ -44,12 +44,11 @@ class Client extends Component
if (!$this->client->isConnected() && !$this->connect()) {
return false;
}
$isSend = $this->client->send(implode("\n", [$cmd, '', serialize($param)]));
$isSend = $this->client->send(Protocol::encode($package, $method, $param));
if ($isSend === false) {
return $this->addError($this->client->errMsg . '(' . $this->client->errCode . ')');
}
defer(fn() => $this->clientRecover());
defer(fn() => $this->client->close());
if (is_bool($unpack = Json::decode($this->client->recv()))) {
$unpack = $this->addError('Service return data format error(500)');
}
@@ -57,22 +56,6 @@ class Client extends Component
}
/**
* @return Client
* @throws Exception
*/
public function clientRecover(): static
{
$host = $this->config['host'] ?? '127.0.0.1';
$port = $this->config['port'] ?? 0;
if ($port < 0) {
return $this;
}
$this->client = null;
return $this;
}
/**
* @return bool
* @throws Exception
@@ -113,7 +96,7 @@ class Client extends Component
if ($port < 0) {
throw new Exception('Related service not have port(404)');
}
$client = new CClient($this->config['mode'] ?? SWOOLE_SOCK_TCP);
$client = new CClient(SWOOLE_SOCK_TCP);
$client->set([
'timeout' => 0.5,
'connect_timeout' => 1.0,
+29
View File
@@ -0,0 +1,29 @@
<?php
namespace Rpc;
use HttpServer\Controller;
use HttpServer\Exception\RequestException;
use Rpc\Annotation\RpcService;
use Server\RequestInterface;
/**
*
*/
#[RpcService(package: "default", protocol: RpcService::PROTOCOL_JSON, server: 'json-rpc')]
class DefaultRpcController extends Controller
{
/**
* @param RequestInterface $request
* @return int
* @throws RequestException
*/
public function getSystemConfig(RequestInterface $request): int
{
return $request->int('a') + $request->int('b');
}
}
+129
View File
@@ -0,0 +1,129 @@
<?php
namespace Rpc;
use Exception;
use JetBrains\PhpStorm\Pure;
use Rpc\Annotation\RpcService;
/**
*
*/
class Protocol
{
private string $version = 'v1.0';
private array $headers = [];
private mixed $data = [];
/**
* @return string
*/
public function getVersion(): string
{
return $this->version;
}
/**
* @return array
*/
public function getHeaders(): array
{
return $this->headers;
}
/**
* @return mixed
*/
public function getData(): mixed
{
return $this->data;
}
/**
* @throws Exception
*/
public static function parse($data): static
{
$protocol = new Protocol();
$protocol->parseHeaders(...explode("\r\n\r\n", $data));
return $protocol;
}
/**
* @param string $service
* @param string $cmd
* @param array $param
* @return string
*/
public static function encode(string $service, string $cmd, array $param = []): string
{
$proto = 'REQUEST tcp/other.protocol v1.0' . "\r\n";
$proto .= ':Source: ' . implode(',', swoole_get_local_ip()) . "\r\n";
$proto .= ':Package: ' . $service . "\r\n";
$proto .= ':Path: ' . $cmd . "\r\n";
$proto .= ':Content-Type: ' . $cmd . "\r\n";
$proto .= ':Method: json-rpc' . "\r\n\r\n";
return $proto . json_encode($param) . "\r\n\r\n";
}
/**
* @param string $body
* @return void
*/
private function parseBody(string $body): void
{
if ($this->headers['Content-Type'] == RpcService::PROTOCOL_JSON) {
$this->data = json_decode($body, true);
} else {
$this->data = unserialize($body);
}
}
/**
* @param string $headers
* @param string $body
* @return void
* @throws Exception
*/
private function parseHeaders(string $headers, string $body): void
{
$explode = explode("\r\n", $headers);
$this->headers = [];
foreach ($explode as $key => $value) {
if ($key == 0) {
if (!str_starts_with($value, 'REQUEST tcp/other.protocol')) {
throw new Exception('Protocol format error.');
}
$this->version = str_replace('REQUEST tcp/other.protocol ', '', $value);
continue;
}
[$name, $item] = explode(': ', $value);
$this->headers[str_replace(':', '', $name)] = $item;
}
if (count(array_diff_key(Service::A_DEFAULT, $this->headers)) > 0) {
throw new Exception('Protocol format error.');
}
$this->parseBody($body);
}
/**
* @return string
*/
#[Pure] public function parseUrl(): string
{
return ':rpc/' . $this->headers['Package'] . '/' . $this->headers['Path'] . '/' . $this->getVersion();
}
}
+10
View File
@@ -0,0 +1,10 @@
<?php
namespace Rpc;
class Registry
{
}
+62 -34
View File
@@ -5,16 +5,26 @@ namespace Rpc;
use Annotation\Inject;
use Exception;
use HttpServer\Exception\RequestException;
use HttpServer\Http\Context;
use HttpServer\Http\Request;
use HttpServer\Route\Node;
use HttpServer\Route\Router;
use Server\Constant;
use Server\Events\OnAfterRequest;
use Kiri\Core\Json;
use Kiri\Abstracts\Config;
use Kiri\Events\EventDispatch;
use Kiri\Events\EventProvider;
use Kiri\Exception\NotFindClassException;
use Kiri\Kiri;
use Swoole\Http\Request;
use Server\Constant;
use Server\Constrict\Response;
use Server\Constrict\ResponseEmitter;
use Server\Events\OnAfterRequest;
use Server\ExceptionHandlerDispatcher;
use Server\ExceptionHandlerInterface;
use Server\RequestInterface;
use Server\ResponseInterface;
use Swoole\Server;
use Server\Constrict\Request as cRequest;
use function Swoole\Coroutine\defer;
@@ -25,8 +35,13 @@ use function Swoole\Coroutine\defer;
class Service extends \Server\Abstracts\Server
{
const RPC_CONNECT = 'RPC::CONNECT';
const RPC_CLOSE = 'RPC::CLOSE';
const A_DEFAULT = [
'Source' => '',
'Package' => '',
'Path' => '',
'Content-Type' => '',
'Method' => ''
];
private Router $router;
@@ -36,17 +51,36 @@ class Service extends \Server\Abstracts\Server
public EventProvider $eventProvider;
public Response $response;
/** @var EventDispatch */
#[Inject(EventDispatch::class)]
public EventDispatch $eventDispatch;
#[Inject(ResponseEmitter::class)]
public ResponseEmitter $responseEmitter;
/**
* @var ExceptionHandlerInterface
*/
public ExceptionHandlerInterface $exceptionHandler;
/**
* @throws Exception
*/
public function init()
{
$this->router = Kiri::getApp('router');
$exceptionHandler = Config::get('exception.http', ExceptionHandlerDispatcher::class);
if (!in_array(ExceptionHandlerInterface::class, class_implements($exceptionHandler))) {
$exceptionHandler = ExceptionHandlerDispatcher::class;
}
$this->exceptionHandler = Kiri::getDi()->get($exceptionHandler);
}
@@ -103,15 +137,18 @@ class Service extends \Server\Abstracts\Server
{
defer(fn() => $this->eventDispatch->dispatch(new OnAfterRequest()));
try {
$client = $server->getClientInfo($fd, $reID);
$request = $this->requestSpl((int)$client['server_port'], $data, $fd);
$result = $this->router->find_path($request)?->dispatch();
$server->send($fd, $result);
$node = $this->router->Branch_search($this->requestSpl($data, $fd));
if (!($node instanceof Node)) {
throw new RequestException('<h2>HTTP 404 Not Found</h2><hr><i>Powered by Swoole</i>', 404);
}
$this->response->setClientId($fd, $reID);
if (!(($responseData = $node->dispatch()) instanceof ResponseInterface)) {
$responseData = $this->response->setContent($responseData)->setStatusCode(200);
}
} catch (\Throwable $exception) {
$server->send($fd, $exception->getMessage());
$responseData = $this->exceptionHandler->emit($exception, $this->response);
} finally {
$this->responseEmitter->sender($server, $responseData);
}
}
@@ -138,34 +175,25 @@ class Service extends \Server\Abstracts\Server
/**
* @param int $server_port
* @param string $data
* @param int $fd
* @return mixed
* @throws NotFindClassException
* @throws \ReflectionException
* @throws Exception
*/
public function requestSpl(int $server_port, string $data, int $fd = 0): \HttpServer\Http\Request
public function requestSpl(string $data, int $fd = 0): RequestInterface
{
$data = Protocol::parse($data);
$sRequest = new Request();
[$cmd, $repeat, $body] = explode("\n", $data);
if (is_null($body) || is_null($cmd) || !empty($repeat)) {
throw new Exception('Protocol format error.');
}
if (is_string($body) && is_null($data = Json::decode($body))) {
throw new Exception('Protocol format error.');
}
$sRequest->fd = $fd;
$sRequest->post = $data;
$sRequest->header['request_uri'] = 'rpc/p' . $server_port . '/' . ltrim($cmd, '/');
$sRequest->header['request_method'] = 'rpc';
$sRequest->setClientId($fd);
$sRequest->setPosts($data->getData());
$sRequest->setHeaders(array_merge($data->getHeaders(), [
'request_uri' => $data->parseUrl(),
'request_method' => $data->getHeaders()['Method']
]));
Context::setContext(Request::class, $sRequest);
return \request();
return di(cRequest::class);
}
}
+52
View File
@@ -0,0 +1,52 @@
<?php
namespace Rpc;
use Annotation\Rpc\RpcConsumer;
use Kiri\Exception\NotFindClassException;
use Rpc\Annotation\RpcService;
/**
*
*/
#[RpcConsumer(package: 'default', method: '', timeout: 10, mode: 'json-rpc')]
class TestRpcClient
{
public string $package = 'default';
public string $protocol = RpcService::PROTOCOL_JSON;
public int $timeout = 10;
public string $method = '';
/**
* @return array
*/
protected function getRegistry(): array
{
return ['127.0.0.1', 5537];
}
/**
* @throws NotFindClassException
* @throws \ReflectionException
* @throws \Exception
*/
public function dispatch(array $param)
{
[$host, $port] = $this->getRegistry();
$client = di(Client::class);
$client->config = ['host' => $host, 'port' => $port, 'timeout' => $this->timeout];
$client->dispatch($this->package, $this->method, $param);
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
use Server\Constant;
return [
'rpc' => [
'name' => 'json-rpc',
'type' => Constant::SERVER_TYPE_TCP,
'host' => '0.0.0.0',
'mode' => SWOOLE_SOCK_TCP,
'port' => 5377,
'setting' => [
'open_tcp_keepalive' => true,
'tcp_keepidle' => 30,
'tcp_keepinterval' => 10,
'tcp_keepcount' => 10,
'open_http_protocol' => false,
'open_websocket_protocol' => false,
],
'events' => [
Constant::CONNECT => [],
Constant::CLOSE => [],
],
'registry' => [
'protocol' => 'consul',
'address' => [
'host' => '47.14.25.45',
'port' => 5527,
'path' => ''
],
],
'consumers' => [
]
]
];