From 4eefe54be096dbc2485f83d26b4c2c066ec02f2e Mon Sep 17 00:00:00 2001 From: as2252258 Date: Sun, 9 Jan 2022 14:00:32 +0800 Subject: [PATCH] e --- .gitignore | 74 ++--- .phpstorm.meta.php | 36 +-- Annotation/JsonRpc.php | 182 +++++------ ClientPool.php | 152 +++++----- InvalidRpcParamsException.php | 46 +-- JsonRpcConsumers.php | 300 +++++++++---------- JsonRpcPoolTransporter.php | 136 ++++----- JsonRpcTransporter.php | 74 ++--- LICENSE | 402 ++++++++++++------------- Luckdraw.php | 302 +++++++++---------- OnJsonRpcInterface.php | 24 +- OnRpcConsumerInterface.php | 16 +- RpcClientInterface.php | 28 +- RpcJsonp.php | 548 +++++++++++++++++----------------- RpcManager.php | 276 ++++++++--------- RpcServiceException.php | 16 +- TraitTransporter.php | 156 +++++----- composer.json | 48 +-- config.php | 154 +++++----- 19 files changed, 1485 insertions(+), 1485 deletions(-) diff --git a/.gitignore b/.gitignore index 9117236..757bb7d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,37 +1,37 @@ -# Created by .ignore support plugin (hsz.mobi) -### Yii template -assets/* -!assets/.gitignore -protected/runtime/* -!protected/runtime/.gitignore -protected/data/*.db -themes/classic/views/ - -### Example user template template -### Example user template - -# IntelliJ project files -.idea -*.iml -out -gen - -db/ -async-queue/ - -composer.lock - -*.log -commands/result -config/setting.php -tests/ -vendor/ -runtime/ - -*.xml -*.lock - -oot -d - -composer.lock +# Created by .ignore support plugin (hsz.mobi) +### Yii template +assets/* +!assets/.gitignore +protected/runtime/* +!protected/runtime/.gitignore +protected/data/*.db +themes/classic/views/ + +### Example user template template +### Example user template + +# IntelliJ project files +.idea +*.iml +out +gen + +db/ +async-queue/ + +composer.lock + +*.log +commands/result +config/setting.php +tests/ +vendor/ +runtime/ + +*.xml +*.lock + +oot +d + +composer.lock diff --git a/.phpstorm.meta.php b/.phpstorm.meta.php index 52dfddd..e1102b5 100644 --- a/.phpstorm.meta.php +++ b/.phpstorm.meta.php @@ -1,18 +1,18 @@ -uniqueId = preg_replace('/(\w{11})(\w{4})(\w{3})(\w{8})(\w{6})/', '$1-$2-$3-$4-$5', md5(__DIR__ . 'Annotation' . md5(Network::local()))); - } - - - /** - * @param mixed $class - * @param mixed|string $method - * @return mixed - * @throws ReflectionException - * @throws ConfigException - */ - public function execute(mixed $class, mixed $method = ''): bool - { - return Kiri::getDi()->get(RpcManager::class)->add($this->service, $class, $this->create()); - } - - - /** - * @throws ConfigException - */ - protected function create(): array - { - $rpcPort = Config::get('rpc.port'); - if (empty($this->checkUrl)) { - $this->checkUrl = Network::local() . ":" . Config::get('rpc.port'); - } - $defaultConfig = [ - "ID" => "rpc.json.{$this->service}." . $this->uniqueId, - "Name" => $this->service, - "EnableTagOverride" => false, - "TaggedAddresses" => [ - "lan_ipv4" => [ - "address" => "127.0.0.1", - "port" => $rpcPort - ], - "wan_ipv4" => [ - "address" => Network::local(), - "port" => $rpcPort - ] - ], - "Check" => [ - "CheckId" => "service:rpc.json.{$this->service}." . $this->uniqueId, - "Name" => "service " . $this->service . ' health check', - "Annotations" => "Script based health check", - "ServiceID" => $this->service, - "TCP" => $this->checkUrl, - "Interval" => "5s", - "Timeout" => "1s", - "DeregisterCriticalServiceAfter" => "30s" - ], - ]; - if (!empty($this->meta)) { - $defaultConfig["Meta"] = $this->meta; - } - if (!empty($this->tags)) { - $defaultConfig["tags"] = $this->tags; - } - return $defaultConfig; - } - - -} +uniqueId = preg_replace('/(\w{11})(\w{4})(\w{3})(\w{8})(\w{6})/', '$1-$2-$3-$4-$5', md5(__DIR__ . 'Annotation' . md5(Network::local()))); + } + + + /** + * @param mixed $class + * @param mixed|string $method + * @return mixed + * @throws ReflectionException + * @throws ConfigException + */ + public function execute(mixed $class, mixed $method = ''): bool + { + return Kiri::getDi()->get(RpcManager::class)->add($this->service, $class, $this->create()); + } + + + /** + * @throws ConfigException + */ + protected function create(): array + { + $rpcPort = Config::get('rpc.port'); + if (empty($this->checkUrl)) { + $this->checkUrl = Network::local() . ":" . Config::get('rpc.port'); + } + $defaultConfig = [ + "ID" => "rpc.json.{$this->service}." . $this->uniqueId, + "Name" => $this->service, + "EnableTagOverride" => false, + "TaggedAddresses" => [ + "lan_ipv4" => [ + "address" => "127.0.0.1", + "port" => $rpcPort + ], + "wan_ipv4" => [ + "address" => Network::local(), + "port" => $rpcPort + ] + ], + "Check" => [ + "CheckId" => "service:rpc.json.{$this->service}." . $this->uniqueId, + "Name" => "service " . $this->service . ' health check', + "Annotations" => "Script based health check", + "ServiceID" => $this->service, + "TCP" => $this->checkUrl, + "Interval" => "5s", + "Timeout" => "1s", + "DeregisterCriticalServiceAfter" => "30s" + ], + ]; + if (!empty($this->meta)) { + $defaultConfig["Meta"] = $this->meta; + } + if (!empty($this->tags)) { + $defaultConfig["tags"] = $this->tags; + } + return $defaultConfig; + } + + +} diff --git a/ClientPool.php b/ClientPool.php index 1d1c4d7..364e274 100644 --- a/ClientPool.php +++ b/ClientPool.php @@ -1,76 +1,76 @@ -name(self::POOL_NAME . '::' . $config['Address'] . '::' . $config['Port'], true); - - $pool = $config['pool'] ?? ['min' => 1, 'max' => 100]; - - 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); - } - -} +name(self::POOL_NAME . '::' . $config['Address'] . '::' . $config['Port'], true); + + $pool = $config['pool'] ?? ['min' => 1, 'max' => 100]; + + 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); + } + +} diff --git a/InvalidRpcParamsException.php b/InvalidRpcParamsException.php index 4635e9a..6e70463 100644 --- a/InvalidRpcParamsException.php +++ b/InvalidRpcParamsException.php @@ -1,23 +1,23 @@ -get_consul($this->name); - $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 - * @throws \ReflectionException - */ - private function requestBody(array $data): ServerRequestInterface - { - $server = Kiri::getDi()->get(ServerRequest::class); - return $server->withBody(new Stream(json_encode($data))); - } - - - /** - * @param string $method - * @param mixed $data - * @param string $version - * @param string $id - * @return mixed - * @throws Exception - * @throws ClientExceptionInterface - */ - public function get(string $method, mixed $data, string $version = '2.0', string $id = ''): ResponseInterface - { - if (empty($id)) $id = Number::create(time()); - - $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 - ]) - ); - } - - - /** - * @param array $data - * @return mixed - * @throws ClientExceptionInterface - * @throws Exception - */ - public function batch(array $data): mixed - { - $config = $this->get_consul($this->name); - $transporter = Kiri::getDi()->get(RpcClientInterface::class); - return $transporter->withConfig($config)->sendRequest( - $this->requestBody($data) - ); - } - - - /** - * @param $service - * @return array - * @throws RpcServiceException|\ReflectionException - * @throws Exception - */ - private function get_consul($service): array - { - if (empty($service)) { - throw new RpcServiceException('You need set rpc service name if used.'); - } - $sf = Kiri::getDi()->get(RpcManager::class)->getServices($service); - if (empty($sf) || !is_array($sf)) { - throw new RpcServiceException('You need set rpc service name if used.'); - } - return $this->_loadRand($sf); - } - - - /** - * @param $services - * @return array - */ - private function _loadRand($services): array - { - $array = []; - foreach ($services as $value) { - $value['Weight'] = $value['Weights']['Passing']; - $array[] = $value; - } - if (count($array) < 2) { - $luck = $array[0]; - } else { - $luck = Luckdraw::luck($array, 'Weight'); - } - return [ - 'Address' => $luck['TaggedAddresses']['wan_ipv4']['Address'], - 'Port' => $luck['TaggedAddresses']['wan_ipv4']['Port'] - ]; - } - -} +get_consul($this->name); + $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 + * @throws \ReflectionException + */ + private function requestBody(array $data): ServerRequestInterface + { + $server = Kiri::getDi()->get(ServerRequest::class); + return $server->withBody(new Stream(json_encode($data))); + } + + + /** + * @param string $method + * @param mixed $data + * @param string $version + * @param string $id + * @return mixed + * @throws Exception + * @throws ClientExceptionInterface + */ + public function get(string $method, mixed $data, string $version = '2.0', string $id = ''): ResponseInterface + { + if (empty($id)) $id = Number::create(time()); + + $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 + ]) + ); + } + + + /** + * @param array $data + * @return mixed + * @throws ClientExceptionInterface + * @throws Exception + */ + public function batch(array $data): mixed + { + $config = $this->get_consul($this->name); + $transporter = Kiri::getDi()->get(RpcClientInterface::class); + return $transporter->withConfig($config)->sendRequest( + $this->requestBody($data) + ); + } + + + /** + * @param $service + * @return array + * @throws RpcServiceException|\ReflectionException + * @throws Exception + */ + private function get_consul($service): array + { + if (empty($service)) { + throw new RpcServiceException('You need set rpc service name if used.'); + } + $sf = Kiri::getDi()->get(RpcManager::class)->getServices($service); + if (empty($sf) || !is_array($sf)) { + throw new RpcServiceException('You need set rpc service name if used.'); + } + return $this->_loadRand($sf); + } + + + /** + * @param $services + * @return array + */ + private function _loadRand($services): array + { + $array = []; + foreach ($services as $value) { + $value['Weight'] = $value['Weights']['Passing']; + $array[] = $value; + } + if (count($array) < 2) { + $luck = $array[0]; + } else { + $luck = Luckdraw::luck($array, 'Weight'); + } + return [ + 'Address' => $luck['TaggedAddresses']['wan_ipv4']['Address'], + 'Port' => $luck['TaggedAddresses']['wan_ipv4']['Port'] + ]; + } + +} diff --git a/JsonRpcPoolTransporter.php b/JsonRpcPoolTransporter.php index d583f77..195a247 100644 --- a/JsonRpcPoolTransporter.php +++ b/JsonRpcPoolTransporter.php @@ -1,68 +1,68 @@ -getBody()->getContents(); - - $response = $this->request($client = $this->getClient(), $content, false); - - $this->pool->push($client, $this->config['Address'], $this->config['Port']); - - return (new Response())->withBody(new Stream($response)); - } - - - /** - * @return Client|\Swoole\Client - * @throws ConfigException - * @throws Exception - */ - private function getClient(): Client|\Swoole\Client - { - $this->config['pool'] = Config::get('rpc.pool', ['max' => 10, 'min' => 1, 'waite' => 60]); - return $this->pool->get($this->config, function () { - return $this->newClient(); - }); - } - - -} +getBody()->getContents(); + + $response = $this->request($client = $this->getClient(), $content, false); + + $this->pool->push($client, $this->config['Address'], $this->config['Port']); + + return (new Response())->withBody(new Stream($response)); + } + + + /** + * @return Client|\Swoole\Client + * @throws ConfigException + * @throws Exception + */ + private function getClient(): Client|\Swoole\Client + { + $this->config['pool'] = Config::get('rpc.pool', ['max' => 10, 'min' => 1, 'waite' => 60]); + return $this->pool->get($this->config, function () { + return $this->newClient(); + }); + } + + +} diff --git a/JsonRpcTransporter.php b/JsonRpcTransporter.php index c937546..b8d3122 100644 --- a/JsonRpcTransporter.php +++ b/JsonRpcTransporter.php @@ -1,37 +1,37 @@ -getBody()->getContents(); - - $response = $this->request($this->newClient(), $content, true); - - return (new Response())->withBody(new Stream($response)); - } - - -} +getBody()->getContents(); + + $response = $this->request($this->newClient(), $content, true); + + return (new Response())->withBody(new Stream($response)); + } + + +} diff --git a/LICENSE b/LICENSE index 261eeb9..29f81d8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,201 +1,201 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Luckdraw.php b/Luckdraw.php index 27f2cd8..f449080 100644 --- a/Luckdraw.php +++ b/Luckdraw.php @@ -1,151 +1,151 @@ - '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], - * ] - * - * @uses $reward = Lucked::luck($data); - */ - public static function luck(array $goods, string $wight = 'probability'): mixed - { - static $class = null; - if ($class === null) $class = new Luckdraw(); - - if (empty($goods)) return null; - - $array = $prob = $alias = []; - - $defaultIndex = 0; - foreach ($goods as $key => $val) { - if ($val[$wight] == 0) $defaultIndex = $key; - $array[] = (float)$val[$wight]; - } - $array[$defaultIndex] = 1 - array_sum($array); - $class->ket($array, $prob, $alias); - - $result = $class->generation($array, $prob, $alias); - if (!isset($goods[$result])) { - return null; - } - return $goods[$result]; - } - - /** - * @param $data - * @param $prob - * @param $alias - * @return mixed - */ - private function generation($data, $prob, $alias): mixed - { - $nums = count($prob) - 1; - - $MAX_P = $this->getMin($data); // 假设最小的几率是万分之一 - $coin_toss = rand(1, $MAX_P) / $MAX_P; // 抛出硬币 - - $col = rand(0, $nums); // 随机落在一列 - $b_head = $coin_toss < $prob[$col]; // 判断是否落在原色 - - return $b_head ? $col : @$alias[$col]; - } - - /** - * @param $num - * @return string - */ - private function getMin($num): string - { - $def = current($num); - foreach ($num as $val) { - if ($val < $def) { - $def = $val; - } - } - - $length = $this->getFloatLength($def) + 1; - - return sprintf('1%0' . $length . 'd', 0); - } - - /** - * @param $float - * @return int - */ - private function getFloatLength($float): int - { - $ex = explode('.', 1 - $float); - - return strlen(end($ex)); - } - - /** - * @param array $data - * @param array $prob - * @param array $alias - */ - private function ket(array $data, array &$prob, array &$alias) - { - $nums = count($data); - $small = $large = []; - for ($i = 0; $i < $nums; ++$i) { - $data[$i] = $data[$i] * $nums; // 扩大倍数,使每列高度可为1 - - /** 分到两个数组,便于组合 */ - if ($data[$i] < 1) { - $small[] = $i; - } else { - $large[] = $i; - } - } - - /** 将超过1的色块与原色拼凑成1 */ - while (!empty($small) && !empty($large)) { - $n_index = array_shift($small); - $a_index = array_shift($large); - - $prob[$n_index] = $data[$n_index]; - $alias[$n_index] = $a_index; - // 重新调整大色块 - $data[$a_index] = ($data[$a_index] + $data[$n_index]) - 1; - - if ($data[$a_index] < 1) { - $small[] = $a_index; - } else { - $large[] = $a_index; - } - } - - /** 剩下大色块都设为1 */ - while (!empty($large)) { - $n_index = array_shift($large); - $prob[$n_index] = 1; - } - - /** 一般是精度问题才会执行这一步 */ - while (!empty($small)) { - $n_index = array_shift($small); - $prob[$n_index] = 1; - } - } - - -} + '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ['name'=> '商品名称', 'probability'=> '概率', 'total'=> '库存'], + * ] + * + * @uses $reward = Lucked::luck($data); + */ + public static function luck(array $goods, string $wight = 'probability'): mixed + { + static $class = null; + if ($class === null) $class = new Luckdraw(); + + if (empty($goods)) return null; + + $array = $prob = $alias = []; + + $defaultIndex = 0; + foreach ($goods as $key => $val) { + if ($val[$wight] == 0) $defaultIndex = $key; + $array[] = (float)$val[$wight]; + } + $array[$defaultIndex] = 1 - array_sum($array); + $class->ket($array, $prob, $alias); + + $result = $class->generation($array, $prob, $alias); + if (!isset($goods[$result])) { + return null; + } + return $goods[$result]; + } + + /** + * @param $data + * @param $prob + * @param $alias + * @return mixed + */ + private function generation($data, $prob, $alias): mixed + { + $nums = count($prob) - 1; + + $MAX_P = $this->getMin($data); // 假设最小的几率是万分之一 + $coin_toss = rand(1, $MAX_P) / $MAX_P; // 抛出硬币 + + $col = rand(0, $nums); // 随机落在一列 + $b_head = $coin_toss < $prob[$col]; // 判断是否落在原色 + + return $b_head ? $col : @$alias[$col]; + } + + /** + * @param $num + * @return string + */ + private function getMin($num): string + { + $def = current($num); + foreach ($num as $val) { + if ($val < $def) { + $def = $val; + } + } + + $length = $this->getFloatLength($def) + 1; + + return sprintf('1%0' . $length . 'd', 0); + } + + /** + * @param $float + * @return int + */ + private function getFloatLength($float): int + { + $ex = explode('.', 1 - $float); + + return strlen(end($ex)); + } + + /** + * @param array $data + * @param array $prob + * @param array $alias + */ + private function ket(array $data, array &$prob, array &$alias) + { + $nums = count($data); + $small = $large = []; + for ($i = 0; $i < $nums; ++$i) { + $data[$i] = $data[$i] * $nums; // 扩大倍数,使每列高度可为1 + + /** 分到两个数组,便于组合 */ + if ($data[$i] < 1) { + $small[] = $i; + } else { + $large[] = $i; + } + } + + /** 将超过1的色块与原色拼凑成1 */ + while (!empty($small) && !empty($large)) { + $n_index = array_shift($small); + $a_index = array_shift($large); + + $prob[$n_index] = $data[$n_index]; + $alias[$n_index] = $a_index; + // 重新调整大色块 + $data[$a_index] = ($data[$a_index] + $data[$n_index]) - 1; + + if ($data[$a_index] < 1) { + $small[] = $a_index; + } else { + $large[] = $a_index; + } + } + + /** 剩下大色块都设为1 */ + while (!empty($large)) { + $n_index = array_shift($large); + $prob[$n_index] = 1; + } + + /** 一般是精度问题才会执行这一步 */ + while (!empty($small)) { + $n_index = array_shift($small); + $prob[$n_index] = 1; + } + } + + +} diff --git a/OnJsonRpcInterface.php b/OnJsonRpcInterface.php index f7a8650..8aa600f 100644 --- a/OnJsonRpcInterface.php +++ b/OnJsonRpcInterface.php @@ -1,12 +1,12 @@ -eventProvider->on(OnBeforeShutdown::class, [$this, 'onBeforeShutdown']); - - scan_directory(APP_PATH . 'rpc', 'Rpc'); - - $this->eventProvider->on(OnWorkerStart::class, [$this, 'consulWatches']); - $this->eventProvider->on(OnServerBeforeStart::class, [$this, 'register']); - - $this->manager = Kiri::getDi()->get(RpcManager::class); - } - - - /** - * @param OnBeforeShutdown $beforeShutdown - * @return void - * @throws ContainerExceptionInterface - * @throws NotFoundExceptionInterface - */ - public function onBeforeShutdown(OnBeforeShutdown $beforeShutdown) - { - $doneList = $this->manager->doneList(); - $agent = $this->container->get(Agent::class); - foreach ($doneList as $value) { - $agent->service->deregister($value['config']['ID']); - $agent->checks->deregister($value['config']['Check']['CheckId']); - } - } - - - /** - * @param OnWorkerStart|OnTaskerStart $server - * @throws ConfigException - */ - public function consulWatches(OnWorkerStart|OnTaskerStart $server) - { - if ($server->workerId != 0) { - return; - } - $async_time = (int)Config::get('consul.async_time', 1000); - Timer::tick($async_time, static function ($timeId) { - if (env('state', 'start') == 'exit') { - Timer::clear($timeId); - return; - } - Kiri::getDi()->get(RpcManager::class)->tick(); - }); - } - - - /** - * @param OnServerBeforeStart $server - */ - public function register(OnServerBeforeStart $server) - { - $this->manager->register(); - } - - - /** - * @param Server $server - * @param int $fd - */ - public function onConnect(Server $server, int $fd): void - { - // TODO: Implement onConnect() method. - } - - - /** - * @param Server $server - * @param int $fd - * @param int $reactor_id - * @param string $data - */ - public function onReceive(Server $server, int $fd, int $reactor_id, string $data): void - { - $data = json_decode($data, true); - if (is_null($data)) { - $this->failure(-32700, 'Parse error语法解析错误'); - } else if (!isset($data['jsonrpc']) || !isset($data['method']) || $data['jsonrpc'] != '2.0') { - $this->failure(-32600, 'Invalid Request无效请求'); - } else { - $this->batchDispatch($server, $fd, $data); - } - } - - - /** - * @param Server $server - * @param int $fd - * @param array $data - * @return void - */ - private function batchDispatch(Server $server, int $fd, array $data): void - { - if (isset($data['jsonrpc'])) { - $dispatch = $this->dispatch($data); - if (!isset($data['id'])) { - $dispatch = [1]; - } - $result = json_encode($dispatch, JSON_UNESCAPED_UNICODE); - } else { - $channel = new Channel($total = count($data)); - foreach ($data as $datum) { - $this->_execute($channel, $datum); - } - $result = []; - for ($i = 0; $i < $total; $i++) { - $result[] = $channel->pop(); - } - } - $server->send($fd, json_encode($result, JSON_UNESCAPED_UNICODE)); - } - - - /** - * @param $channel - * @param $datum - */ - private function _execute($channel, $datum) - { - Coroutine::create(function () use ($channel, $datum) { - if (empty($datum) || !isset($datum['jsonrpc'])) { - $channel->push($this->failure(-32700, 'Parse error语法解析错误')); - } else if (!isset($datum['method'])) { - $channel->push($this->failure(-32700, 'Parse error语法解析错误')); - } else { - $dispatch = $this->dispatch($datum); - if (!isset($dispatch['id'])) { - $dispatch = [1]; - } - $channel->push($dispatch); - } - }); - } - - - /** - * @param $data - * @return array - */ - private function dispatch($data): array - { - try { - [$handler, $params] = $this->container->get(RpcManager::class)->get($data['service'], $data['method']); - if (is_null($handler)) { - throw new \Exception('Method not found', -32601); - } else { - Context::setContext(RequestInterface::class, $this->createServerRequest($params)); - - return $this->handler($handler); - } - } catch (\Throwable $throwable) { - $code = $throwable->getCode() == 0 ? -32603 : $throwable->getCode(); - return $this->failure($code, jTraceEx($throwable), [], $data['id'] ?? null); - } - } - - - /** - * @param $params - * @return ServerRequestInterface - * @throws \Exception - */ - private function createServerRequest($params): ServerRequestInterface - { - return (new ServerRequest())->withParsedBody($params); - } - - - /** - * @param Handler $handler - * @return array - */ - private function handler(Handler $handler): array - { - return [ - 'jsonrpc' => '2.0', - 'result' => call_user_func($handler->callback, ...$handler->params), - 'id' => $data['id'] ?? null - ]; - } - - - /** - * @param $code - * @param $message - * @param array $data - * @param null $id - * @return array - */ - protected function failure($code, $message, array $data = [], $id = null): array - { - $error = [ - 'jsonrpc' => '2.0', - 'error' => [ - 'code' => $code, - 'message' => $message, - 'data' => $data - ] - ]; - if (!is_null($id)) { - $error['id'] = $id; - } - return $error; - } - - - /** - * @param Server $server - * @param int $fd - */ - public function onClose(Server $server, int $fd): void - { - // TODO: Implement onClose() method. - } -} +eventProvider->on(OnBeforeShutdown::class, [$this, 'onBeforeShutdown']); + + scan_directory(APP_PATH . 'rpc', 'Rpc'); + + $this->eventProvider->on(OnWorkerStart::class, [$this, 'consulWatches']); + $this->eventProvider->on(OnServerBeforeStart::class, [$this, 'register']); + + $this->manager = Kiri::getDi()->get(RpcManager::class); + } + + + /** + * @param OnBeforeShutdown $beforeShutdown + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function onBeforeShutdown(OnBeforeShutdown $beforeShutdown) + { + $doneList = $this->manager->doneList(); + $agent = $this->container->get(Agent::class); + foreach ($doneList as $value) { + $agent->service->deregister($value['config']['ID']); + $agent->checks->deregister($value['config']['Check']['CheckId']); + } + } + + + /** + * @param OnWorkerStart|OnTaskerStart $server + * @throws ConfigException + */ + public function consulWatches(OnWorkerStart|OnTaskerStart $server) + { + if ($server->workerId != 0) { + return; + } + $async_time = (int)Config::get('consul.async_time', 1000); + Timer::tick($async_time, static function ($timeId) { + if (env('state', 'start') == 'exit') { + Timer::clear($timeId); + return; + } + Kiri::getDi()->get(RpcManager::class)->tick(); + }); + } + + + /** + * @param OnServerBeforeStart $server + */ + public function register(OnServerBeforeStart $server) + { + $this->manager->register(); + } + + + /** + * @param Server $server + * @param int $fd + */ + public function onConnect(Server $server, int $fd): void + { + // TODO: Implement onConnect() method. + } + + + /** + * @param Server $server + * @param int $fd + * @param int $reactor_id + * @param string $data + */ + public function onReceive(Server $server, int $fd, int $reactor_id, string $data): void + { + $data = json_decode($data, true); + if (is_null($data)) { + $this->failure(-32700, 'Parse error语法解析错误'); + } else if (!isset($data['jsonrpc']) || !isset($data['method']) || $data['jsonrpc'] != '2.0') { + $this->failure(-32600, 'Invalid Request无效请求'); + } else { + $this->batchDispatch($server, $fd, $data); + } + } + + + /** + * @param Server $server + * @param int $fd + * @param array $data + * @return void + */ + private function batchDispatch(Server $server, int $fd, array $data): void + { + if (isset($data['jsonrpc'])) { + $dispatch = $this->dispatch($data); + if (!isset($data['id'])) { + $dispatch = [1]; + } + $result = json_encode($dispatch, JSON_UNESCAPED_UNICODE); + } else { + $channel = new Channel($total = count($data)); + foreach ($data as $datum) { + $this->_execute($channel, $datum); + } + $result = []; + for ($i = 0; $i < $total; $i++) { + $result[] = $channel->pop(); + } + } + $server->send($fd, json_encode($result, JSON_UNESCAPED_UNICODE)); + } + + + /** + * @param $channel + * @param $datum + */ + private function _execute($channel, $datum) + { + Coroutine::create(function () use ($channel, $datum) { + if (empty($datum) || !isset($datum['jsonrpc'])) { + $channel->push($this->failure(-32700, 'Parse error语法解析错误')); + } else if (!isset($datum['method'])) { + $channel->push($this->failure(-32700, 'Parse error语法解析错误')); + } else { + $dispatch = $this->dispatch($datum); + if (!isset($dispatch['id'])) { + $dispatch = [1]; + } + $channel->push($dispatch); + } + }); + } + + + /** + * @param $data + * @return array + */ + private function dispatch($data): array + { + try { + [$handler, $params] = $this->container->get(RpcManager::class)->get($data['service'], $data['method']); + if (is_null($handler)) { + throw new \Exception('Method not found', -32601); + } else { + Context::setContext(RequestInterface::class, $this->createServerRequest($params)); + + return $this->handler($handler); + } + } catch (\Throwable $throwable) { + $code = $throwable->getCode() == 0 ? -32603 : $throwable->getCode(); + return $this->failure($code, jTraceEx($throwable), [], $data['id'] ?? null); + } + } + + + /** + * @param $params + * @return ServerRequestInterface + * @throws \Exception + */ + private function createServerRequest($params): ServerRequestInterface + { + return (new ServerRequest())->withParsedBody($params); + } + + + /** + * @param Handler $handler + * @return array + */ + private function handler(Handler $handler): array + { + return [ + 'jsonrpc' => '2.0', + 'result' => call_user_func($handler->callback, ...$handler->params), + 'id' => $data['id'] ?? null + ]; + } + + + /** + * @param $code + * @param $message + * @param array $data + * @param null $id + * @return array + */ + protected function failure($code, $message, array $data = [], $id = null): array + { + $error = [ + 'jsonrpc' => '2.0', + 'error' => [ + 'code' => $code, + 'message' => $message, + 'data' => $data + ] + ]; + if (!is_null($id)) { + $error['id'] = $id; + } + return $error; + } + + + /** + * @param Server $server + * @param int $fd + */ + public function onClose(Server $server, int $fd): void + { + // TODO: Implement onClose() method. + } +} diff --git a/RpcManager.php b/RpcManager.php index 1e05e22..503117c 100644 --- a/RpcManager.php +++ b/RpcManager.php @@ -1,138 +1,138 @@ -get(Health::class)->setQuery('passing=true')->service($serviceName); - if ($lists->getStatusCode() != 200) { - return; - } - $body = json_decode($lists->getBody(), true); - $file = storage('.rpc.clients.' . md5($serviceName), 'rpc'); - if (!empty($body) && is_array($body)) { - file_put_contents($file, json_encode(array_column($body, 'Service')), LOCK_EX); - } else { - file_put_contents($file, json_encode([]), LOCK_EX); - } - } - - - /** - * @throws ReflectionException - */ - public function tick(): void - { - foreach ($this->_rpc as $name => $list) { - $this->async($name); - } - } - - - /** - * @param $serviceName - * @return array - * @throws \Exception - */ - public function getServices($serviceName): array - { - $file = storage('.rpc.clients.' . md5($serviceName), 'rpc'); - if (!file_exists($file) || filesize($file) < 10) { - $this->async($serviceName); - } - $content = json_decode(file_get_contents($file), true); - if (empty($content) || !is_array($content)) { - return []; - } - return $content; - } - - - /** - * @param string $name - * @param string $class - * @param array $serviceConfig - * @return bool - * @throws ReflectionException - */ - public function add(string $name, string $class, array $serviceConfig): bool - { - $methods = Kiri::getDi()->getReflect($class); - $lists = $methods->getMethods(\ReflectionMethod::IS_PUBLIC); - - if (!isset($this->_rpc[$name])) { - $this->_rpc[$name] = ['methods' => [], 'id' => $serviceConfig['ID'], 'config' => $serviceConfig]; - } - - foreach ($lists as $reflection) { - if ($reflection->getDeclaringClass() != $class) { - continue; - } - $methodName = $reflection->getName(); - $this->_rpc[$name]['methods'][$methodName] = [new Handler('/', [$class, $methodName]), null]; - } - return true; - } - - - /** - * @return array - */ - public function doneList(): array - { - $array = []; - foreach ($this->_rpc as $list) { - $array[] = $list; - } - return $array; - } - - - /** - */ - public function register() - { - $agent = Kiri::getDi()->get(Agent::class); - foreach ($this->_rpc as $list) { - $data = $agent->service->register($list['config']); - if ($data->getStatusCode() != 200) { - return; - } - } - } - - - /** - * @param string $name - * @param string $method - * @return mixed - */ - public function get(string $name, string $method): array - { - return $this->_rpc[$name]['methods'][$method] ?? [null, null]; - } - -} +get(Health::class)->setQuery('passing=true')->service($serviceName); + if ($lists->getStatusCode() != 200) { + return; + } + $body = json_decode($lists->getBody(), true); + $file = storage('.rpc.clients.' . md5($serviceName), 'rpc'); + if (!empty($body) && is_array($body)) { + file_put_contents($file, json_encode(array_column($body, 'Service')), LOCK_EX); + } else { + file_put_contents($file, json_encode([]), LOCK_EX); + } + } + + + /** + * @throws ReflectionException + */ + public function tick(): void + { + foreach ($this->_rpc as $name => $list) { + $this->async($name); + } + } + + + /** + * @param $serviceName + * @return array + * @throws \Exception + */ + public function getServices($serviceName): array + { + $file = storage('.rpc.clients.' . md5($serviceName), 'rpc'); + if (!file_exists($file) || filesize($file) < 10) { + $this->async($serviceName); + } + $content = json_decode(file_get_contents($file), true); + if (empty($content) || !is_array($content)) { + return []; + } + return $content; + } + + + /** + * @param string $name + * @param string $class + * @param array $serviceConfig + * @return bool + * @throws ReflectionException + */ + public function add(string $name, string $class, array $serviceConfig): bool + { + $methods = Kiri::getDi()->getReflect($class); + $lists = $methods->getMethods(\ReflectionMethod::IS_PUBLIC); + + if (!isset($this->_rpc[$name])) { + $this->_rpc[$name] = ['methods' => [], 'id' => $serviceConfig['ID'], 'config' => $serviceConfig]; + } + + foreach ($lists as $reflection) { + if ($reflection->getDeclaringClass() != $class) { + continue; + } + $methodName = $reflection->getName(); + $this->_rpc[$name]['methods'][$methodName] = [new Handler('/', [$class, $methodName]), null]; + } + return true; + } + + + /** + * @return array + */ + public function doneList(): array + { + $array = []; + foreach ($this->_rpc as $list) { + $array[] = $list; + } + return $array; + } + + + /** + */ + public function register() + { + $agent = Kiri::getDi()->get(Agent::class); + foreach ($this->_rpc as $list) { + $data = $agent->service->register($list['config']); + if ($data->getStatusCode() != 200) { + return; + } + } + } + + + /** + * @param string $name + * @param string $method + * @return mixed + */ + public function get(string $name, string $method): array + { + return $this->_rpc[$name]['methods'][$method] ?? [null, null]; + } + +} diff --git a/RpcServiceException.php b/RpcServiceException.php index fecc542..0bb379d 100644 --- a/RpcServiceException.php +++ b/RpcServiceException.php @@ -1,8 +1,8 @@ -config = $config; - return $this; - } - - - /** - * @param Client|Coroutine\Client $client - * @param $content - * @param bool $isClose - * @return mixed - */ - private function request(Client|Coroutine\Client $client, $content, bool $isClose): mixed - { - $client->send($content); - $read = $client->recv(); - if ($isClose) { - $client->close(); - } - return $read; - } - - - /** - * @return Client|Coroutine\Client - * @throws Exception - */ - private function newClient(): Coroutine\Client|Client - { - $alias = $this->alias($this->config); - $client = $this->clients[$alias] ?? null; - if (is_null($client)) { - $client = Context::inCoroutine() ? new Coroutine\Client(SWOOLE_SOCK_TCP) : new Client(SWOOLE_SOCK_TCP); - $this->clients[$alias] = $client; - } - [$host, $port] = [$this->config['Address'], $this->config['Port']]; - if (!$client->isConnected() && !$client->connect($host, $port, 60)) { - throw new Exception('connect fail.'); - } - return $client; - } - - - /** - * @param array $config - * @return string - */ - private function alias(array $config): string - { - return $config['Address'] . '::' . $config['Port']; - } - - -} +config = $config; + return $this; + } + + + /** + * @param Client|Coroutine\Client $client + * @param $content + * @param bool $isClose + * @return mixed + */ + private function request(Client|Coroutine\Client $client, $content, bool $isClose): mixed + { + $client->send($content); + $read = $client->recv(); + if ($isClose) { + $client->close(); + } + return $read; + } + + + /** + * @return Client|Coroutine\Client + * @throws Exception + */ + private function newClient(): Coroutine\Client|Client + { + $alias = $this->alias($this->config); + $client = $this->clients[$alias] ?? null; + if (is_null($client)) { + $client = Context::inCoroutine() ? new Coroutine\Client(SWOOLE_SOCK_TCP) : new Client(SWOOLE_SOCK_TCP); + $this->clients[$alias] = $client; + } + [$host, $port] = [$this->config['Address'], $this->config['Port']]; + if (!$client->isConnected() && !$client->connect($host, $port, 60)) { + throw new Exception('connect fail.'); + } + return $client; + } + + + /** + * @param array $config + * @return string + */ + private function alias(array $config): string + { + return $config['Address'] . '::' . $config['Port']; + } + + +} diff --git a/composer.json b/composer.json index 35f6ef6..a0c76a0 100644 --- a/composer.json +++ b/composer.json @@ -1,24 +1,24 @@ -{ - "name": "game-worker/kiri-rpc", - "description": "kiri-rpc", - "authors": [ - { - "name": "XiangLin", - "email": "as2252258@163.com" - } - ], - "license": "MIT", - "require": { - "php": ">=8.0", - "ext-json": "*", - "psr/http-client": "^1.0", - "psr/http-message": "^1.0" - }, - "autoload": { - "psr-4": { - "Kiri\\Rpc\\": "./" - } - }, - "require-dev": { - } -} +{ + "name": "game-worker/kiri-rpc", + "description": "kiri-rpc", + "authors": [ + { + "name": "XiangLin", + "email": "as2252258@163.com" + } + ], + "license": "MIT", + "require": { + "php": ">=8.0", + "ext-json": "*", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "autoload": { + "psr-4": { + "Kiri\\Rpc\\": "./" + } + }, + "require-dev": { + } +} diff --git a/config.php b/config.php index 01e7763..289e0a1 100644 --- a/config.php +++ b/config.php @@ -1,77 +1,77 @@ - [ - 'name' => 'json-rpc', - 'type' => Constant::SERVER_TYPE_BASE, - 'mode' => SWOOLE_SOCK_TCP, - 'host' => '0.0.0.0', - 'port' => 9526, - 'settings' => [ - - ], - 'events' => [ - Constant::RECEIVE => [RpcJsonp::class, 'onReceive'] - ], - - - 'consumers' => [ - 'class' => TestRpcService::class, - 'name' => 'test-rpc', - 'package' => 'test', - 'register' => [ - 'host' => '', - 'port' => '' - ] - ] - ], - - - 'service' => [ - [ - "datacenter" => "dc1", - "id" => "40e4a748-2192-161a-0510-9bf59fe950b5", - "node" => "FriendRpcService", - "skipNodeUpdate" => false, - "service" => [ - "id" => "redis1", - "service" => "FriendRpcService", - "address" => "172.26.221.211", - "taggedAddresses" => [ - "lan" => [ - "address" => "127.0.0.1", - "port" => 8000 - ], - "wan" => [ - "address" => "172.26.221.211", - "port" => 80 - ] - ], - "meta" => [ - "redis_version" => "4.0" - ], - "port" => 8000 - ], - "check" => [ - "node" => "t2.320", - "checkId" => "service:redis1", - "name" => "Redis health check", - "Annotations" => "Script based health check", - "status" => "passing", - "serviceID" => "redis1", - "definition" => [ - "http" => "172.26.221.211:9527", - "interval" => "5s", - "timeout" => "1s", - "deregisterCriticalServiceAfter" => "30s" - ], - ], - ] - - ] -]; + [ + 'name' => 'json-rpc', + 'type' => Constant::SERVER_TYPE_BASE, + 'mode' => SWOOLE_SOCK_TCP, + 'host' => '0.0.0.0', + 'port' => 9526, + 'settings' => [ + + ], + 'events' => [ + Constant::RECEIVE => [RpcJsonp::class, 'onReceive'] + ], + + + 'consumers' => [ + 'class' => TestRpcService::class, + 'name' => 'test-rpc', + 'package' => 'test', + 'register' => [ + 'host' => '', + 'port' => '' + ] + ] + ], + + + 'service' => [ + [ + "datacenter" => "dc1", + "id" => "40e4a748-2192-161a-0510-9bf59fe950b5", + "node" => "FriendRpcService", + "skipNodeUpdate" => false, + "service" => [ + "id" => "redis1", + "service" => "FriendRpcService", + "address" => "172.26.221.211", + "taggedAddresses" => [ + "lan" => [ + "address" => "127.0.0.1", + "port" => 8000 + ], + "wan" => [ + "address" => "172.26.221.211", + "port" => 80 + ] + ], + "meta" => [ + "redis_version" => "4.0" + ], + "port" => 8000 + ], + "check" => [ + "node" => "t2.320", + "checkId" => "service:redis1", + "name" => "Redis health check", + "Annotations" => "Script based health check", + "status" => "passing", + "serviceID" => "redis1", + "definition" => [ + "http" => "172.26.221.211:9527", + "interval" => "5s", + "timeout" => "1s", + "deregisterCriticalServiceAfter" => "30s" + ], + ], + ] + + ] +];