正在显示
32 个修改的文件
包含
3 行增加
和
2207 行删除
1 | { | 1 | { |
2 | - "name": "aukey/aukeySwrpc", | 2 | + "name": "aukey/swrpc", |
3 | "description": "基于swoole的rpc库", | 3 | "description": "基于swoole的rpc库", |
4 | "license": "MIT", | 4 | "license": "MIT", |
5 | "authors": [ | 5 | "authors": [ |
@@ -20,8 +20,8 @@ | @@ -20,8 +20,8 @@ | ||
20 | }, | 20 | }, |
21 | "autoload": { | 21 | "autoload": { |
22 | "psr-4": { | 22 | "psr-4": { |
23 | - "AukeySwrpc\\": "src/", | ||
24 | - "AukeySwrpcTests\\": "tests/" | 23 | + "Swrpc\\": "src/", |
24 | + "SwrpcTests\\": "tests/" | ||
25 | }, | 25 | }, |
26 | "classmap": [ | 26 | "classmap": [ |
27 | "src/" | 27 | "src/" |
src/AukeySwrpcProvider.php
已删除
100644 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | -use Illuminate\Support\ServiceProvider; | ||
6 | - | ||
7 | -class AukeyAukeySwrpcProvider extends ServiceProvider | ||
8 | -{ | ||
9 | - public function boot() | ||
10 | - { | ||
11 | - $this->loadMigrationsFrom(__DIR__ . '/database/migrations'); | ||
12 | - if ($this->app->runningInConsole()) { | ||
13 | - $this->commands([ | ||
14 | - \AukeyDataCenter\Commands\CreateBaseCode::class, | ||
15 | - \AukeyDataCenter\Commands\SheinReturnOrderCom::class, | ||
16 | - \AukeyDataCenter\Commands\SheinProductCom::class, | ||
17 | - \AukeyDataCenter\Commands\SheinBrandCom::class, | ||
18 | - ]); | ||
19 | - } | ||
20 | - } | ||
21 | - | ||
22 | - public function register() | ||
23 | - { | ||
24 | - $provides = [ | ||
25 | - 'AukeyDataCenter\Http\RouteServiceProvider', | ||
26 | - ]; | ||
27 | - foreach ($provides as $provider) { | ||
28 | - $this->app->register($provider); | ||
29 | - } | ||
30 | - } | ||
31 | -} |
src/Client.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | - | ||
6 | -use Swoole\Client as SwClient; | ||
7 | -use AukeySwrpc\Exceptions\RpcException; | ||
8 | -use AukeySwrpc\Packer\PackerInterface; | ||
9 | -use AukeySwrpc\Packer\SerializeLengthPacker; | ||
10 | -use AukeySwrpc\Register\RegisterInterface; | ||
11 | -use AukeySwrpc\Register\Service; | ||
12 | -use AukeySwrpc\Request\Request; | ||
13 | - | ||
14 | -/** | ||
15 | - * Class Client | ||
16 | - * | ||
17 | - * @package AukeySwrpc | ||
18 | - * @author pengjch 202439 11:36:25 | ||
19 | - */ | ||
20 | -class Client | ||
21 | -{ | ||
22 | - protected $services = []; | ||
23 | - protected $connects = []; | ||
24 | - | ||
25 | - | ||
26 | - const STRATEGY_RANDOM = 1; | ||
27 | - const STRATEGY_WEIGHT = 2; | ||
28 | - | ||
29 | - protected $mode; | ||
30 | - protected $timeout = 3; | ||
31 | - protected array $options; | ||
32 | - protected string $module; | ||
33 | - protected int $strategy; | ||
34 | - protected ?RegisterInterface $register = null; | ||
35 | - protected ?PackerInterface $packer = null; | ||
36 | - | ||
37 | - protected array $defaultOptions | ||
38 | - = [ | ||
39 | - 'open_length_check' => true, | ||
40 | - 'package_length_type' => 'N', | ||
41 | - 'package_length_offset' => 0, //第N个字节是包长度的值 | ||
42 | - 'package_body_offset' => 4, //第几个字节开始计算长度 | ||
43 | - 'package_max_length' => 81920, //协议最大长度 | ||
44 | - ]; | ||
45 | - | ||
46 | - /** | ||
47 | - * Client constructor. | ||
48 | - * | ||
49 | - * @param string $module | ||
50 | - * @param array $services | ||
51 | - * @param int $mode | ||
52 | - * @param int $timeout | ||
53 | - * @param array $options | ||
54 | - */ | ||
55 | - public function __construct(string $module, array $services, $mode = SWOOLE_SOCK_TCP, $timeout = 3, $options = []) | ||
56 | - { | ||
57 | - $this->module = $module; | ||
58 | - $this->services = $services; | ||
59 | - $this->mode = $mode; | ||
60 | - $this->timeout = $timeout; | ||
61 | - if (empty($options)) { | ||
62 | - $options = $this->defaultOptions; | ||
63 | - } | ||
64 | - $this->options = $options; | ||
65 | - | ||
66 | - } | ||
67 | - | ||
68 | - /** | ||
69 | - * @param string $module | ||
70 | - * @param string $host | ||
71 | - * @param int $port | ||
72 | - * @param int $mode | ||
73 | - * @param array $options | ||
74 | - * @return Client | ||
75 | - * @author pengjch 2024313 18:31:17 | ||
76 | - */ | ||
77 | - public static function create( | ||
78 | - string $module, | ||
79 | - string $host, | ||
80 | - int $port, | ||
81 | - $mode = SWOOLE_SOCK_TCP, | ||
82 | - $timeout = 3, | ||
83 | - $options = [] | ||
84 | - ): Client { | ||
85 | - $service = Service::build($host, $port, 1); | ||
86 | - return new static($module, [$service], $mode, $timeout, $options); | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * @param string $module | ||
91 | - * @param RegisterInterface $register | ||
92 | - * @param int $strategy | ||
93 | - * @param int $mode | ||
94 | - * @param int $timeout | ||
95 | - * @param array $options | ||
96 | - * @return Client | ||
97 | - * @author pengjch 2024313 18:31:22 | ||
98 | - */ | ||
99 | - public static function createBalancer( | ||
100 | - string $module, | ||
101 | - RegisterInterface $register, | ||
102 | - $strategy = self::STRATEGY_RANDOM, | ||
103 | - $mode = SWOOLE_SOCK_TCP, | ||
104 | - $timeout = 3, | ||
105 | - $options = [] | ||
106 | - ): Client { | ||
107 | - $client = new static($module, [], $mode, $timeout, $options); | ||
108 | - $client->strategy = $strategy; | ||
109 | - $client->addRegister($register); | ||
110 | - return $client; | ||
111 | - } | ||
112 | - | ||
113 | - /** | ||
114 | - * @param RegisterInterface $register | ||
115 | - * @return $this | ||
116 | - * @author pengjch 2024313 18:27:20 | ||
117 | - */ | ||
118 | - public function addRegister(RegisterInterface $register): Client | ||
119 | - { | ||
120 | - $this->register = $register; | ||
121 | - $this->services = $this->register->getServices($this->module); | ||
122 | - return $this; | ||
123 | - } | ||
124 | - | ||
125 | - /** | ||
126 | - * @param PackerInterface $packer | ||
127 | - * @return $this | ||
128 | - * @author pengjch 2024313 18:27:24 | ||
129 | - */ | ||
130 | - public function addPacker(PackerInterface $packer): Client | ||
131 | - { | ||
132 | - $this->packer = $packer; | ||
133 | - return $this; | ||
134 | - } | ||
135 | - | ||
136 | - /** | ||
137 | - * @return SwClient | ||
138 | - * @throws RpcException | ||
139 | - * @author pengjch 2024313 18:23:37 | ||
140 | - */ | ||
141 | - public function connect(): SwClient | ||
142 | - { | ||
143 | - $n = count($this->services); | ||
144 | - if ($n == 0) { | ||
145 | - throw new RpcException('No services available'); | ||
146 | - } | ||
147 | - | ||
148 | - /** @var Service $service */ | ||
149 | - if ($n == 1) { //单个服务节点 | ||
150 | - $service = $this->services[0]; | ||
151 | - $key = $service->getHost() . '_' . $service->getPort(); | ||
152 | - } else { //多个服务节点 | ||
153 | - $key = $this->getConnectKey(); | ||
154 | - } | ||
155 | - | ||
156 | - if (isset($this->connects[$key]) && $this->connects[$key]->isConnected()) { | ||
157 | - return $this->connects[$key]; | ||
158 | - } | ||
159 | - $client = new SwClient($this->mode ?: SWOOLE_SOCK_TCP); | ||
160 | - if (!$client->connect($service->getHost(), $service->getPort(), $this->timeout ?? 3)) { | ||
161 | - throw new RpcException("connect failed. Error: {$client->errCode}"); | ||
162 | - } | ||
163 | - $client->set($this->options); | ||
164 | - $this->connects[$key] = $client; | ||
165 | - return $this->connects[$key]; | ||
166 | - } | ||
167 | - | ||
168 | - /** | ||
169 | - * 发送请求 | ||
170 | - * | ||
171 | - * @param Request $request | ||
172 | - * @return mixed | ||
173 | - * @throws RpcException | ||
174 | - * @author pengjch 202439 13:35:25 | ||
175 | - */ | ||
176 | - public function send(Request $request) | ||
177 | - { | ||
178 | - /** @var \Swoole\Client $conn */ | ||
179 | - $conn = $this->connect(); | ||
180 | - | ||
181 | - if (!$this->packer) { | ||
182 | - $this->packer = new SerializeLengthPacker([ | ||
183 | - 'package_length_type' => $options['package_length_type'] ?? 'N', | ||
184 | - 'package_body_offset' => $options['package_body_offset'] ?? 4, | ||
185 | - ]); | ||
186 | - } | ||
187 | - | ||
188 | - $request->setModule($this->module); | ||
189 | - $conn->send($this->packer->pack($request)); | ||
190 | - | ||
191 | - /** @var Response $response */ | ||
192 | - $response = @unserialize($conn->recv()); | ||
193 | - if (!($response instanceof Response)) { | ||
194 | - throw new RpcException('The server return type is not a AukeySwrpc\Response'); | ||
195 | - } | ||
196 | - if ($response->code == Response::RES_ERROR) { | ||
197 | - throw new RpcException($response->msg); | ||
198 | - } | ||
199 | - | ||
200 | - return $response->data['result'] ?? null; | ||
201 | - } | ||
202 | - | ||
203 | - /** | ||
204 | - * @return string | ||
205 | - * @author pengjch 2024313 18:20:38 | ||
206 | - */ | ||
207 | - public function getConnectKey(): string | ||
208 | - { | ||
209 | - /** @var Service $service */ | ||
210 | - if ($this->strategy == self::STRATEGY_RANDOM) { | ||
211 | - $service = array_rand($this->services); | ||
212 | - return $service->getHost() . '_' . $service->getPort(); | ||
213 | - } else { | ||
214 | - /** @var Service $service */ | ||
215 | - foreach ($this->services as $service) { | ||
216 | - $totalWeight += $service->getWeight(); | ||
217 | - $sort[] = $service->getWeight(); | ||
218 | - $serviceArr[] = $service->toArray(); | ||
219 | - } | ||
220 | - | ||
221 | - array_multisort($serviceArr, SORT_DESC, $sort); | ||
222 | - | ||
223 | - $start = 0; | ||
224 | - $rand = rand(1, $totalWeight); | ||
225 | - foreach ($serviceArr as $service) { | ||
226 | - if ($start + $service['weight'] >= $rand) { | ||
227 | - return $service['host'] . '_' . $service['port']; | ||
228 | - } | ||
229 | - $start = $start + $service['weight']; | ||
230 | - } | ||
231 | - } | ||
232 | - } | ||
233 | - | ||
234 | - /** | ||
235 | - * 关闭客户端连接 | ||
236 | - * | ||
237 | - * @return mixed | ||
238 | - * @author pengjch 2024310 9:16:46 | ||
239 | - */ | ||
240 | - public function close() | ||
241 | - { | ||
242 | - foreach ($this->connects as $connect) { | ||
243 | - $connect->close(true); | ||
244 | - } | ||
245 | - } | ||
246 | - | ||
247 | - /** | ||
248 | - * 刷新节点服务信息 | ||
249 | - * 客户端使用长连接的情况下,需要起一个定时器来定时更新节点服务信息 | ||
250 | - * | ||
251 | - * @author pengjch 2024313 18:24:23 | ||
252 | - */ | ||
253 | - public function refreshServices() | ||
254 | - { | ||
255 | - if ($this->register) { | ||
256 | - $this->services = $this->register->getServices($this->module); | ||
257 | - $this->connects = []; | ||
258 | - } | ||
259 | - } | ||
260 | -} |
src/Event.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | -trait Event | ||
6 | -{ | ||
7 | - public function OnWorkerStart(\Swoole\Server $server, int $workerId) | ||
8 | - { | ||
9 | - } | ||
10 | - | ||
11 | - public function onStart(\Swoole\Server $server) | ||
12 | - { | ||
13 | - } | ||
14 | - | ||
15 | - public function onShutdown(\Swoole\Server $server) | ||
16 | - { | ||
17 | - | ||
18 | - } | ||
19 | -} |
src/Exceptions/RequestException.php
已删除
100755 → 0
src/Exceptions/RpcException.php
已删除
100755 → 0
src/Exceptions/TypeException.php
已删除
100755 → 0
src/LogicService.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Tracer\TracerContext; | ||
7 | -use Zipkin\Endpoint; | ||
8 | -use Zipkin\Reporters\Http; | ||
9 | -use Zipkin\Samplers\BinarySampler; | ||
10 | -use Zipkin\TracingBuilder; | ||
11 | - | ||
12 | -/** | ||
13 | - * Class LogicService | ||
14 | - * | ||
15 | - * @package AukeySwrpc | ||
16 | - * @author pengjch 2024311 11:10:18 | ||
17 | - */ | ||
18 | -class LogicService | ||
19 | -{ | ||
20 | - protected $params; | ||
21 | - protected $module; | ||
22 | - protected $tracerUrl; | ||
23 | - protected $tracerContext; | ||
24 | - protected $clients = []; | ||
25 | - | ||
26 | - /** | ||
27 | - * @return static | ||
28 | - * @author pengjch 2024311 11:4:5 | ||
29 | - */ | ||
30 | - public static function factory() | ||
31 | - { | ||
32 | - return new static(); | ||
33 | - } | ||
34 | - | ||
35 | - /** | ||
36 | - * 初始化链路追踪器 | ||
37 | - * | ||
38 | - * @param $func | ||
39 | - * @author pengjch 2024311 11:3:36 | ||
40 | - */ | ||
41 | - public function initTracer($func) | ||
42 | - { | ||
43 | - $reporterUrl = $this->tracerUrl ?: 'http://127.0.0.1:9411/api/v2/spans'; | ||
44 | - $endpoint = Endpoint::create($this->module); | ||
45 | - $reporter = new Http(['endpoint_url' => $reporterUrl]); | ||
46 | - $sampler = BinarySampler::createAsAlwaysSample(); | ||
47 | - $tracing = TracingBuilder::create() | ||
48 | - ->havingLocalEndpoint($endpoint) | ||
49 | - ->havingSampler($sampler) | ||
50 | - ->havingReporter($reporter) | ||
51 | - ->build(); | ||
52 | - $tracer = $tracing->getTracer(); | ||
53 | - $span = $tracer->newTrace(); | ||
54 | - $span->setName($func); | ||
55 | - $span->start(); | ||
56 | - $span->finish(); | ||
57 | - $tracer->flush(); | ||
58 | - | ||
59 | - $ctx = $span->getContext(); | ||
60 | - if ($this->tracerContext) { | ||
61 | - $this->tracerContext->setTraceID($ctx->getTraceId()); | ||
62 | - $this->tracerContext->setParentID($ctx->getSpanId()); | ||
63 | - $this->tracerContext->setReporterUrl($reporterUrl); | ||
64 | - } else { | ||
65 | - $this->tracerContext = TracerContext::create($ctx->getTraceId(), $ctx->getSpanId(), $reporterUrl); | ||
66 | - } | ||
67 | - } | ||
68 | - | ||
69 | - /** | ||
70 | - * @param $context | ||
71 | - * @return $this | ||
72 | - * @author pengjch 2024311 11:18:43 | ||
73 | - */ | ||
74 | - public function setTracerContext($context) | ||
75 | - { | ||
76 | - $this->tracerContext = $context; | ||
77 | - return $this; | ||
78 | - } | ||
79 | - | ||
80 | - /** | ||
81 | - * @param $func | ||
82 | - * @return null | ||
83 | - * @author pengjch 2024311 11:4:1 | ||
84 | - */ | ||
85 | - public function getTracerContext($func) | ||
86 | - { | ||
87 | - if (empty($this->tracerUrl)) { | ||
88 | - return null; | ||
89 | - } | ||
90 | - if (empty($this->tracerContext)) { | ||
91 | - $this->initTracer($func); | ||
92 | - } | ||
93 | - return $this->tracerContext; | ||
94 | - } | ||
95 | - | ||
96 | - /** | ||
97 | - * @param array $params | ||
98 | - * @return $this | ||
99 | - * @author pengjch 2024311 11:15:47 | ||
100 | - */ | ||
101 | - public function setParams(array $params) | ||
102 | - { | ||
103 | - $this->params = $params; | ||
104 | - return $this; | ||
105 | - } | ||
106 | - | ||
107 | - /** | ||
108 | - * @param string $url | ||
109 | - * @return static $this | ||
110 | - * @author pengjch 2024311 11:15:35 | ||
111 | - */ | ||
112 | - public function setTracerUrl(string $url) | ||
113 | - { | ||
114 | - $this->tracerUrl = $url; | ||
115 | - return $this; | ||
116 | - } | ||
117 | - | ||
118 | - /** | ||
119 | - * @param string $name | ||
120 | - * @return $this | ||
121 | - * @author pengjch 2024311 11:59:4 | ||
122 | - */ | ||
123 | - public function setModule(string $name) | ||
124 | - { | ||
125 | - $this->module = $name; | ||
126 | - return $this; | ||
127 | - } | ||
128 | -} |
src/Middlewares/MiddlewareInterface.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Middlewares; | ||
4 | - | ||
5 | - | ||
6 | -use Closure; | ||
7 | -use AukeySwrpc\Request\Request; | ||
8 | -use AukeySwrpc\Response; | ||
9 | - | ||
10 | -/** | ||
11 | - * Interface MiddlewareInterface | ||
12 | - * | ||
13 | - * @package AukeySwrpc\Middlewares | ||
14 | - * @author pengjch 202439 11:37:39 | ||
15 | - */ | ||
16 | -interface MiddlewareInterface | ||
17 | -{ | ||
18 | - function handle(Request $request, Closure $next): Response; | ||
19 | -} |
src/Middlewares/TraceMiddleware.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Middlewares; | ||
4 | - | ||
5 | - | ||
6 | -use Closure; | ||
7 | -use AukeySwrpc\Request\Request; | ||
8 | -use AukeySwrpc\Response; | ||
9 | -use Zipkin\Endpoint; | ||
10 | -use Zipkin\Propagation\TraceContext; | ||
11 | -use Zipkin\Reporters\Http; | ||
12 | -use Zipkin\Samplers\BinarySampler; | ||
13 | -use Zipkin\TracingBuilder; | ||
14 | - | ||
15 | -/** | ||
16 | - * 链路追踪中间件 | ||
17 | - * Class TraceMiddleware | ||
18 | - * | ||
19 | - * @package AukeySwrpc\Middlewares | ||
20 | - * @author pengjch 2024310 16:41:6 | ||
21 | - */ | ||
22 | -class TraceMiddleware implements MiddlewareInterface | ||
23 | -{ | ||
24 | - function handle(Request $request, Closure $next): Response | ||
25 | - { | ||
26 | - $context = $request->getTraceContext(); | ||
27 | - if (!$context) { | ||
28 | - return $next($request); | ||
29 | - } | ||
30 | - | ||
31 | - $traceContext = TraceContext::create($context->getTraceID(), $context->getParentID(), null, true); | ||
32 | - $endpoint = Endpoint::create($request->getModule()); | ||
33 | - $reporter = new Http(['endpoint_url' => $context->getReporterUrl()]); | ||
34 | - $sampler = BinarySampler::createAsAlwaysSample(); | ||
35 | - $tracing = TracingBuilder::create() | ||
36 | - ->havingLocalEndpoint($endpoint) | ||
37 | - ->havingSampler($sampler) | ||
38 | - ->havingReporter($reporter) | ||
39 | - ->build(); | ||
40 | - | ||
41 | - $tracer = $tracing->getTracer(); | ||
42 | - $span = $tracer->newChild($traceContext); | ||
43 | - $span->setName($request->getMethod()); | ||
44 | - $span->start(); | ||
45 | - $span->tag('请求参数', serialize($request->getParams())); | ||
46 | - $request->setTraceContext($span->getContext()->getTraceId(), $span->getContext() | ||
47 | - ->getSpanId(), $context->getReporterUrl()); | ||
48 | - | ||
49 | - $start = microtime(true); | ||
50 | - $result = $next($request); | ||
51 | - $end = microtime(true); | ||
52 | - | ||
53 | - $span->tag('响应状态码code', $result->code); | ||
54 | - $span->tag('响应提示语msg', $result->msg); | ||
55 | - $span->tag('响应耗时', $end - $start); | ||
56 | - $span->finish(); | ||
57 | - $tracer->flush(); | ||
58 | - | ||
59 | - return $result; | ||
60 | - } | ||
61 | -} |
src/Packer/PackerInterface.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Packer; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Request\Request; | ||
7 | - | ||
8 | -/** | ||
9 | - * Interface PackerInterface | ||
10 | - * | ||
11 | - * @package AukeySwrpc\Packer | ||
12 | - * @author pengjch 202439 11:37:10 | ||
13 | - */ | ||
14 | -interface PackerInterface | ||
15 | -{ | ||
16 | - function pack(Request $data):string; | ||
17 | - function unpack(string $data); | ||
18 | -} |
src/Packer/SerializeEofPacker.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Packer; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Request\Request; | ||
7 | - | ||
8 | -/** | ||
9 | - * Class SerializeEofPacker | ||
10 | - * | ||
11 | - * @package AukeySwrpc\Packer | ||
12 | - * @author pengjch 202439 11:37:17 | ||
13 | - */ | ||
14 | -class SerializeEofPacker implements PackerInterface | ||
15 | -{ | ||
16 | - /** | ||
17 | - * @var string | ||
18 | - */ | ||
19 | - protected $eof; | ||
20 | - | ||
21 | - public function __construct(array $options = []) | ||
22 | - { | ||
23 | - $this->eof = $options['settings']['package_eof'] ?? "\r\n"; | ||
24 | - } | ||
25 | - | ||
26 | - public function pack(Request $data): string | ||
27 | - { | ||
28 | - return serialize($data); | ||
29 | - } | ||
30 | - | ||
31 | - public function unpack(string $data) | ||
32 | - { | ||
33 | - return unserialize($data); | ||
34 | - } | ||
35 | -} |
src/Packer/SerializeLengthPacker.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Packer; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Request\Request; | ||
7 | - | ||
8 | -/** | ||
9 | - * Class SerializeLengthPacker | ||
10 | - * | ||
11 | - * @package AukeySwrpc\Packer | ||
12 | - * @author pengjch 202439 11:37:27 | ||
13 | - */ | ||
14 | -class SerializeLengthPacker implements PackerInterface | ||
15 | -{ | ||
16 | - /** | ||
17 | - * @var string | ||
18 | - */ | ||
19 | - protected $type; | ||
20 | - | ||
21 | - /** | ||
22 | - * @var int | ||
23 | - */ | ||
24 | - protected $length; | ||
25 | - | ||
26 | - protected $defaultOptions | ||
27 | - = [ | ||
28 | - 'package_length_type' => 'N', | ||
29 | - 'package_body_offset' => 4, | ||
30 | - ]; | ||
31 | - | ||
32 | - public function __construct(array $options = []) | ||
33 | - { | ||
34 | - $options = array_merge($this->defaultOptions, $options['settings'] ?? []); | ||
35 | - | ||
36 | - $this->type = $options['package_length_type']; | ||
37 | - $this->length = $options['package_body_offset']; | ||
38 | - } | ||
39 | - | ||
40 | - public function pack(Request $data): string | ||
41 | - { | ||
42 | - $data = serialize($data); | ||
43 | - return pack($this->type, strlen($data)) . $data; | ||
44 | - } | ||
45 | - | ||
46 | - public function unpack(string $data) | ||
47 | - { | ||
48 | - $package = unpack('N', $data); | ||
49 | - $len = $package[1]; | ||
50 | - | ||
51 | - //合并unserialize和substr,以减少内存拷贝 https://wenda.swoole.com/detail/107587 | ||
52 | - if (function_exists('swoole_substr_unserialize')) { | ||
53 | - return swoole_substr_unserialize($data, $this->length, $len); | ||
54 | - } | ||
55 | - | ||
56 | - $data = substr($data, $this->length, $len); | ||
57 | - return unserialize($data); | ||
58 | - } | ||
59 | -} |
src/Register/Consul.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Register; | ||
4 | - | ||
5 | - | ||
6 | -use SensioLabs\Consul\ServiceFactory; | ||
7 | -use SensioLabs\Consul\Services\Agent; | ||
8 | -use SensioLabs\Consul\Services\AgentInterface as AgentInterfaceAlias; | ||
9 | -use SensioLabs\Consul\Services\Catalog; | ||
10 | -use SensioLabs\Consul\Services\CatalogInterface; | ||
11 | -use SensioLabs\Consul\Services\Health; | ||
12 | -use AukeySwrpc\Exceptions\RpcException; | ||
13 | - | ||
14 | -class Consul implements RegisterInterface | ||
15 | -{ | ||
16 | - protected $sf; | ||
17 | - protected array $options; | ||
18 | - protected array $serviceCache | ||
19 | - = [ | ||
20 | - 'ttl' => 10, | ||
21 | - 'services' => [], | ||
22 | - 'lastUpdateTime' => 0, | ||
23 | - ]; | ||
24 | - | ||
25 | - public function __construct($uri = 'http://127.0.0.1:8500', $options = []) | ||
26 | - { | ||
27 | - $this->options = $options; | ||
28 | - $this->sf = new ServiceFactory([ | ||
29 | - 'base_uri' => $uri | ||
30 | - ]); | ||
31 | - } | ||
32 | - | ||
33 | - public function getName(): string | ||
34 | - { | ||
35 | - return 'Consul'; | ||
36 | - } | ||
37 | - | ||
38 | - /** | ||
39 | - * 注册节点 | ||
40 | - * | ||
41 | - * @param string $module | ||
42 | - * @param string $host | ||
43 | - * @param $port | ||
44 | - * @param int $weight | ||
45 | - * @author pengjch 202439 23:17:5 | ||
46 | - */ | ||
47 | - public function register($module, $host, $port, $weight = 1) | ||
48 | - { | ||
49 | - $id = $host . '_' . $port; | ||
50 | - /** @var Agent $agent */ | ||
51 | - $agent = $this->sf->get(AgentInterfaceAlias::class); | ||
52 | - $agent->registerService([ | ||
53 | - 'ID' => $id, | ||
54 | - 'Name' => $module, | ||
55 | - 'Port' => $port, | ||
56 | - 'Address' => $host, | ||
57 | - 'Tags' => [ | ||
58 | - 'port_' . $port, | ||
59 | - ], | ||
60 | - 'Weights' => [ | ||
61 | - 'Passing' => $weight, | ||
62 | - 'Warning' => 1, | ||
63 | - ], | ||
64 | - 'Check' => [ | ||
65 | - 'TCP' => $host . ':' . $port, | ||
66 | - 'Interval' => $this->options['interval'] ?? '10s', | ||
67 | - 'Timeout' => $this->options['timeout'] ?? '5s', | ||
68 | - 'DeregisterCriticalServiceAfter' => $this->options['deregisterCriticalServiceAfter'] ?? '30s', | ||
69 | - ], | ||
70 | - ]); | ||
71 | - } | ||
72 | - | ||
73 | - /** | ||
74 | - * 注销节点 | ||
75 | - * http://127.0.0.1:8500/v1/agent/service/deregister/service_id | ||
76 | - * | ||
77 | - * @param $host | ||
78 | - * @param $port | ||
79 | - * @author pengjch 202439 23:16:51 | ||
80 | - */ | ||
81 | - public function unRegister($host, $port) | ||
82 | - { | ||
83 | - $id = $host . '_' . $port; | ||
84 | - /** @var Agent $agent */ | ||
85 | - $agent = $this->sf->get(AgentInterfaceAlias::class); | ||
86 | - $agent->deregisterService($id); | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * 获取模块下所有的服务 | ||
91 | - * | ||
92 | - * @param string $module | ||
93 | - * @return array | ||
94 | - * @author pengjch 2024310 9:44:16 | ||
95 | - */ | ||
96 | - public function getServices(string $module): array | ||
97 | - { | ||
98 | - $cache = $this->serviceCache; | ||
99 | - $ttl = $this->options['ttl'] ?? $cache['ttl']; | ||
100 | - | ||
101 | - //本地缓存所有节点信息,避免每次请求都要从consul拉一遍数据 | ||
102 | - if ($cache['lastUpdateTime'] + $ttl < time()) { | ||
103 | - $health = new Health(); | ||
104 | - $servers = $health->service($module)->json(); | ||
105 | - if (empty($servers)) { | ||
106 | - return []; | ||
107 | - } | ||
108 | - $result = []; | ||
109 | - foreach ($servers as $server) { | ||
110 | - $result[] = Service::build($server['Service']['Address'], $server['Service']['Port'], $server['Service']['Weights']['Passing']); | ||
111 | - } | ||
112 | - $cache['service'] = $result; | ||
113 | - $cache['lastUpdateTime'] = time(); | ||
114 | - } | ||
115 | - | ||
116 | - return $cache['service']; | ||
117 | - } | ||
118 | - | ||
119 | - /** | ||
120 | - * 随机获取一个服务 | ||
121 | - * | ||
122 | - * @param string $module | ||
123 | - * @return Service | ||
124 | - * @author pengjch 2024310 9:44:27 | ||
125 | - */ | ||
126 | - public function getRandomService(string $module): Service | ||
127 | - { | ||
128 | - $services = $this->getServices($module); | ||
129 | - if (!$services) { | ||
130 | - throw new RpcException('It has not register module'); | ||
131 | - } | ||
132 | - | ||
133 | - return $services[rand(0, count($services) - 1)]; | ||
134 | - } | ||
135 | - | ||
136 | - /** | ||
137 | - * 获取权重服务 | ||
138 | - * | ||
139 | - * @param string $module | ||
140 | - * @return Service | ||
141 | - * @author pengjch 2024310 9:44:38 | ||
142 | - */ | ||
143 | - public function getWeightService(string $module): Service | ||
144 | - { | ||
145 | - $serviceArr = []; | ||
146 | - $totalWeight = 0; | ||
147 | - $services = $this->getServices($module); | ||
148 | - if (!$services) { | ||
149 | - throw new RpcException('It has not register module'); | ||
150 | - } | ||
151 | - | ||
152 | - /** @var Service $service */ | ||
153 | - foreach ($services as $service) { | ||
154 | - $totalWeight += $service->getWeight(); | ||
155 | - $sort[] = $service->getWeight(); | ||
156 | - $serviceArr[] = $service->toArray(); | ||
157 | - } | ||
158 | - | ||
159 | - array_multisort($serviceArr, SORT_DESC, $sort); | ||
160 | - | ||
161 | - $start = 0; | ||
162 | - $rand = rand(1, $totalWeight); | ||
163 | - foreach ($serviceArr as $service) { | ||
164 | - if ($start + $service['weight'] >= $rand) { | ||
165 | - return Service::build($service['host'], $service['port'], $service['weight']); | ||
166 | - } | ||
167 | - $start = $start + $service['weight']; | ||
168 | - } | ||
169 | - } | ||
170 | -} |
src/Register/RegisterInterface.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Register; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * Interface RegisterInterface | ||
8 | - * | ||
9 | - * @package AukeySwrpc\Register | ||
10 | - * @author pengjch 202439 16:23:35 | ||
11 | - */ | ||
12 | -interface RegisterInterface | ||
13 | -{ | ||
14 | - function getName(): string; | ||
15 | - | ||
16 | - function register($module, $host, $port, $weight = 1); | ||
17 | - | ||
18 | - function unRegister($host, $port); | ||
19 | - | ||
20 | - function getServices(string $module): array; | ||
21 | - | ||
22 | - function getRandomService(string $module): Service; | ||
23 | - | ||
24 | - function getWeightService(string $module): Service; | ||
25 | -} |
src/Register/Service.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Register; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * 注册中心服务 | ||
8 | - * Class Service | ||
9 | - * | ||
10 | - * @package AukeySwrpc\Register | ||
11 | - * @author pengjch 2024311 10:25:46 | ||
12 | - */ | ||
13 | -class Service | ||
14 | -{ | ||
15 | - protected $host; | ||
16 | - protected $port; | ||
17 | - protected $weight; | ||
18 | - | ||
19 | - public function __construct($host, $port, $weight) | ||
20 | - { | ||
21 | - $this->host = $host; | ||
22 | - $this->port = $port; | ||
23 | - $this->weight = $weight; | ||
24 | - } | ||
25 | - | ||
26 | - public static function build($host, $port, $weight) | ||
27 | - { | ||
28 | - return new static($host, $port, $weight); | ||
29 | - } | ||
30 | - | ||
31 | - public function getHost() | ||
32 | - { | ||
33 | - return $this->host; | ||
34 | - } | ||
35 | - | ||
36 | - public function getPort() | ||
37 | - { | ||
38 | - return $this->port; | ||
39 | - } | ||
40 | - | ||
41 | - public function getWeight() | ||
42 | - { | ||
43 | - return $this->weight; | ||
44 | - } | ||
45 | - | ||
46 | - public function toArray(): array | ||
47 | - { | ||
48 | - return [ | ||
49 | - 'host' => $this->host, | ||
50 | - 'port' => $this->port, | ||
51 | - 'weight' => $this->weight | ||
52 | - ]; | ||
53 | - } | ||
54 | -} |
src/Request/AsyncRequest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Request; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * Class AsyncRequest | ||
8 | - * | ||
9 | - * @package AukeySwrpc\Request | ||
10 | - * @author pengjch 2024313 9:10:2 | ||
11 | - */ | ||
12 | -class AsyncRequest extends Request | ||
13 | -{ | ||
14 | - public function init() | ||
15 | - { | ||
16 | - $this->setSync(false); | ||
17 | - $this->setSystem(false); | ||
18 | - } | ||
19 | -} |
src/Request/Request.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Request; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Tracer\TracerContext; | ||
7 | - | ||
8 | -abstract class Request | ||
9 | -{ | ||
10 | - protected string $module; | ||
11 | - protected string $method; | ||
12 | - protected array $params; | ||
13 | - protected bool $isSync = true; //是否同步请求,默认是 | ||
14 | - protected bool $isSystem = false; //是否系统请求,默认否 | ||
15 | - protected $error; | ||
16 | - protected ?TracerContext $traceContext; | ||
17 | - | ||
18 | - public static function create($method, $params, ?TracerContext $traceContext = null) | ||
19 | - { | ||
20 | - return new static ($method, $params, $traceContext); | ||
21 | - } | ||
22 | - | ||
23 | - public function __construct($method, $params, ?TracerContext $traceContext = null) | ||
24 | - { | ||
25 | - $this->method = $method; | ||
26 | - $this->params = $params; | ||
27 | - $this->traceContext = $traceContext; | ||
28 | - $this->init(); | ||
29 | - } | ||
30 | - | ||
31 | - abstract public function init(); | ||
32 | - | ||
33 | - public function getModule(): string | ||
34 | - { | ||
35 | - return $this->module; | ||
36 | - } | ||
37 | - | ||
38 | - public function getMethod(): string | ||
39 | - { | ||
40 | - return $this->method; | ||
41 | - } | ||
42 | - | ||
43 | - public function getParams(): array | ||
44 | - { | ||
45 | - return $this->params; | ||
46 | - } | ||
47 | - | ||
48 | - public function setParams(array $params) | ||
49 | - { | ||
50 | - $this->params = $params; | ||
51 | - } | ||
52 | - | ||
53 | - public function setModule(string $name) | ||
54 | - { | ||
55 | - $this->module = $name; | ||
56 | - } | ||
57 | - | ||
58 | - public function mergeParams(array $params) | ||
59 | - { | ||
60 | - $this->params = array_merge($this->params, $params); | ||
61 | - } | ||
62 | - | ||
63 | - public function getTraceContext(): ?TracerContext | ||
64 | - { | ||
65 | - return $this->traceContext; | ||
66 | - } | ||
67 | - | ||
68 | - public function setTraceContext($traceID, $parentID, $url) | ||
69 | - { | ||
70 | - $this->traceContext = TracerContext::create($traceID, $parentID, $url); | ||
71 | - } | ||
72 | - | ||
73 | - public function setSync(bool $value) | ||
74 | - { | ||
75 | - $this->isSync = $value; | ||
76 | - } | ||
77 | - | ||
78 | - public function isSync(): bool | ||
79 | - { | ||
80 | - return $this->isSync; | ||
81 | - } | ||
82 | - | ||
83 | - public function setSystem(bool $value) | ||
84 | - { | ||
85 | - $this->isSystem = $value; | ||
86 | - } | ||
87 | - | ||
88 | - public function isSystem(): bool | ||
89 | - { | ||
90 | - return $this->isSystem; | ||
91 | - } | ||
92 | - | ||
93 | - public function getError() | ||
94 | - { | ||
95 | - return $this->error; | ||
96 | - } | ||
97 | - | ||
98 | - public function setError($err) | ||
99 | - { | ||
100 | - $this->error = $err; | ||
101 | - } | ||
102 | -} |
src/Request/SyncRequest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Request; | ||
4 | - | ||
5 | -/** | ||
6 | - * Class SyncRequest | ||
7 | - * | ||
8 | - * @package AukeySwrpc\Request | ||
9 | - * @author pengjch 2024313 9:9:54 | ||
10 | - */ | ||
11 | -class SyncRequest extends Request | ||
12 | -{ | ||
13 | - public function init() | ||
14 | - { | ||
15 | - $this->setSync(true); | ||
16 | - $this->setSystem(false); | ||
17 | - } | ||
18 | -} |
src/Request/SystemRequest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Request; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * Class AsyncRequest | ||
8 | - * | ||
9 | - * @package AukeySwrpc\Request | ||
10 | - * @author pengjch 2024313 9:10:2 | ||
11 | - */ | ||
12 | -class SystemRequest extends Request | ||
13 | -{ | ||
14 | - public function init() | ||
15 | - { | ||
16 | - $this->setSync(true); | ||
17 | - $this->setSystem(true); | ||
18 | - } | ||
19 | -} |
src/Response.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * Class Response | ||
8 | - * | ||
9 | - * @package AukeySwrpc | ||
10 | - * @author pengjch 202439 11:36:9 | ||
11 | - */ | ||
12 | -class Response | ||
13 | -{ | ||
14 | - const RES_ERROR = 0; | ||
15 | - const RES_SUCCESS = 1; | ||
16 | - | ||
17 | - public string $msg; | ||
18 | - public int $code; | ||
19 | - public array $data; | ||
20 | - | ||
21 | - public function __construct($code, $msg, $data) | ||
22 | - { | ||
23 | - $this->data = $data; | ||
24 | - $this->code = $code; | ||
25 | - $this->msg = $msg; | ||
26 | - } | ||
27 | - | ||
28 | - public static function error($msg, $code = self::RES_ERROR, $data = []): Response | ||
29 | - { | ||
30 | - return new static($code, $msg, $data); | ||
31 | - } | ||
32 | - | ||
33 | - public static function success($data = [], $msg = 'success', $code = self::RES_SUCCESS): Response | ||
34 | - { | ||
35 | - return new static($code, $msg, $data); | ||
36 | - } | ||
37 | -} |
src/Server.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | - | ||
6 | -use Monolog\Handler\StreamHandler; | ||
7 | -use Monolog\Logger; | ||
8 | -use Psr\Log\LoggerInterface; | ||
9 | -use AukeySwrpc\Middlewares\TraceMiddleware; | ||
10 | -use AukeySwrpc\Packer\SerializeLengthPacker; | ||
11 | -use AukeySwrpc\Register\RegisterInterface; | ||
12 | -use AukeySwrpc\Middlewares\MiddlewareInterface; | ||
13 | -use AukeySwrpc\Packer\PackerInterface; | ||
14 | -use AukeySwrpc\Request\Request; | ||
15 | - | ||
16 | -/** | ||
17 | - * Class Server | ||
18 | - * | ||
19 | - * @package AukeySwrpc | ||
20 | - * @author pengjch 202439 11:35:52 | ||
21 | - */ | ||
22 | -class Server | ||
23 | -{ | ||
24 | - use Event; | ||
25 | - | ||
26 | - protected string $module; | ||
27 | - protected string $host; | ||
28 | - protected int $port; | ||
29 | - protected int $weight = 1; | ||
30 | - protected array $options; | ||
31 | - protected array $defaultOptions | ||
32 | - = [ | ||
33 | - 'open_length_check' => true, | ||
34 | - 'package_length_type' => 'N', | ||
35 | - 'package_length_offset' => 0, //第N个字节是包长度的值 | ||
36 | - 'package_body_offset' => 4, //第几个字节开始计算长度 | ||
37 | - 'package_max_length' => 81920, //协议最大长度 | ||
38 | - ]; | ||
39 | - | ||
40 | - /** @var PackerInterface $packer */ | ||
41 | - protected $packer; | ||
42 | - | ||
43 | - /** @var Service $service */ | ||
44 | - protected $service; | ||
45 | - | ||
46 | - /** @var LoggerInterface $logger */ | ||
47 | - protected $logger; | ||
48 | - | ||
49 | - /** @var RegisterInterface $register */ | ||
50 | - protected $register; | ||
51 | - | ||
52 | - /** @var \Swoole\Server $server */ | ||
53 | - protected \Swoole\Server $server; | ||
54 | - | ||
55 | - private array $middlewares; | ||
56 | - | ||
57 | - public function __construct( | ||
58 | - string $module, | ||
59 | - string $host, | ||
60 | - int $port, | ||
61 | - array $options = [], | ||
62 | - $mode = SWOOLE_PROCESS, | ||
63 | - $socketType = SWOOLE_SOCK_TCP, | ||
64 | - LoggerInterface $logger = null | ||
65 | - ) { | ||
66 | - $this->module = $module; | ||
67 | - $this->host = $host; | ||
68 | - $this->port = $port; | ||
69 | - | ||
70 | - $this->setDefaultOptions($options); | ||
71 | - $this->setDefaultLogger($logger); | ||
72 | - $this->setCoreMiddleware(); | ||
73 | - | ||
74 | - $this->service = new Service($this->logger); | ||
75 | - | ||
76 | - $server = new \Swoole\Server($host, $port, $mode ?: SWOOLE_PROCESS, $socketType ?: SWOOLE_SOCK_TCP); | ||
77 | - $server->set($this->options); | ||
78 | - $server->on('Start', [$this, 'onStart']); | ||
79 | - $server->on('Shutdown', [$this, 'onShutdown']); | ||
80 | - $server->on('WorkerStart', [$this, 'onWorkerStart']); | ||
81 | - $server->on('Connect', [$this, 'OnConnect']); | ||
82 | - $server->on('Receive', [$this, 'OnReceive']); | ||
83 | - $server->on('Close', [$this, 'OnClose']); | ||
84 | - $server->on('Task', [$this, 'OnTask']); | ||
85 | - $server->on('Finish', [$this, 'OnFinish']); | ||
86 | - $this->server = $server; | ||
87 | - } | ||
88 | - | ||
89 | - /** | ||
90 | - * 设置节点权重 | ||
91 | - * | ||
92 | - * @param int $weight | ||
93 | - * @return Server | ||
94 | - * @author pengjch 2024313 10:55:39 | ||
95 | - */ | ||
96 | - public function weight(int $weight): Server | ||
97 | - { | ||
98 | - $this->weight = $weight; | ||
99 | - return $this; | ||
100 | - } | ||
101 | - | ||
102 | - /** | ||
103 | - * 设置默认选项 | ||
104 | - * | ||
105 | - * @param $options | ||
106 | - * @author pengjch 2024311 10:35:3 | ||
107 | - */ | ||
108 | - protected function setDefaultOptions($options) | ||
109 | - { | ||
110 | - if (empty($options)) { | ||
111 | - $options = $this->defaultOptions; | ||
112 | - } | ||
113 | - | ||
114 | - $this->options = $options; | ||
115 | - | ||
116 | - //请求数量超过10000重启 | ||
117 | - if (empty($this->options['max_request'])) { | ||
118 | - $this->options['max_request'] = 10000; | ||
119 | - } | ||
120 | - //默认task数量 | ||
121 | - if (empty($this->options['task_worker_num'])) { | ||
122 | - $this->options['task_worker_num'] = swoole_cpu_num() * 2; | ||
123 | - } | ||
124 | - //task请求数超过10000则重启 | ||
125 | - if (empty($this->options['task_max_request'])) { | ||
126 | - $this->options['task_max_request'] = 10000; | ||
127 | - } | ||
128 | - //10s没有数据传输就进行检测 | ||
129 | - if (empty($this->options['tcp_keepidle'])) { | ||
130 | - $this->options['tcp_keepidle'] = 10; | ||
131 | - } | ||
132 | - //3s探测一次 | ||
133 | - if (empty($this->options['tcp_keepinterval'])) { | ||
134 | - $this->options['tcp_keepinterval'] = 3; | ||
135 | - } | ||
136 | - //探测的次数,超过5次后还没回包close此连接 | ||
137 | - if (empty($this->options['tcp_keepcount'])) { | ||
138 | - $this->options['tcp_keepcount'] = 5; | ||
139 | - } | ||
140 | - } | ||
141 | - | ||
142 | - /** | ||
143 | - * 设置默认日志处理器 | ||
144 | - * | ||
145 | - * @param LoggerInterface|null $logger | ||
146 | - * @author pengjch 2024311 10:34:19 | ||
147 | - */ | ||
148 | - protected function setDefaultLogger(LoggerInterface $logger = null) | ||
149 | - { | ||
150 | - if (empty($logger)) { | ||
151 | - $logger = new Logger('AukeySwrpc'); | ||
152 | - $logger->pushHandler(new StreamHandler(STDOUT, Logger::DEBUG)); | ||
153 | - } | ||
154 | - $this->logger = $logger; | ||
155 | - } | ||
156 | - | ||
157 | - /** | ||
158 | - * 设置核心中间件 | ||
159 | - * | ||
160 | - * @author pengjch 2024311 10:34:5 | ||
161 | - */ | ||
162 | - protected function setCoreMiddleware() | ||
163 | - { | ||
164 | - $this->middlewares[] = TraceMiddleware::class; | ||
165 | - } | ||
166 | - | ||
167 | - /** | ||
168 | - * 添加中间件,支持匿名函数和实现类 | ||
169 | - * addMiddleware | ||
170 | - * | ||
171 | - * @param mixed ...$middlewares | ||
172 | - * @author pengjch 202439 11:35:11 | ||
173 | - */ | ||
174 | - public function addMiddleware(...$middlewares) | ||
175 | - { | ||
176 | - foreach ($middlewares as $middleware) { | ||
177 | - if (is_string($middleware) && class_exists($middleware)) { | ||
178 | - $middleware = new $middleware(); | ||
179 | - } | ||
180 | - if (!($middleware instanceof \Closure) && !($middleware instanceof MiddlewareInterface)) { | ||
181 | - $this->logger->warning('Skip illegal Middleware.'); | ||
182 | - continue; | ||
183 | - } | ||
184 | - $this->middlewares[] = $middleware; | ||
185 | - } | ||
186 | - } | ||
187 | - | ||
188 | - /** | ||
189 | - * 添加服务 | ||
190 | - * addService | ||
191 | - * | ||
192 | - * @param $service | ||
193 | - * @param string $prefix | ||
194 | - * @return Server | ||
195 | - * @author pengjch 202439 11:35:2 | ||
196 | - */ | ||
197 | - public function addService($service, $prefix = ''): Server | ||
198 | - { | ||
199 | - $this->service->addInstance($service, $prefix); | ||
200 | - return $this; | ||
201 | - } | ||
202 | - | ||
203 | - /** | ||
204 | - * @param $key | ||
205 | - * @return mixed|null | ||
206 | - * @author pengjch 2024312 16:11:12 | ||
207 | - */ | ||
208 | - public function getService($key) | ||
209 | - { | ||
210 | - return $this->service->getService($key); | ||
211 | - } | ||
212 | - | ||
213 | - /** | ||
214 | - * 注册发现中心 | ||
215 | - * | ||
216 | - * @param $register | ||
217 | - * @return Server | ||
218 | - * @author pengjch 202439 16:38:51 | ||
219 | - */ | ||
220 | - public function addRegister($register): Server | ||
221 | - { | ||
222 | - $this->register = $register; | ||
223 | - return $this; | ||
224 | - } | ||
225 | - | ||
226 | - /** | ||
227 | - * 添加日志处理器 | ||
228 | - * | ||
229 | - * @param $logger | ||
230 | - * @author pengjch 202439 12:20:57 | ||
231 | - */ | ||
232 | - public function addLogger($logger) | ||
233 | - { | ||
234 | - $this->logger = $logger; | ||
235 | - } | ||
236 | - | ||
237 | - /** | ||
238 | - * 添加包解析器 | ||
239 | - * | ||
240 | - * @param $packer | ||
241 | - * @author pengjch 202439 12:45:53 | ||
242 | - */ | ||
243 | - public function addPacker($packer) | ||
244 | - { | ||
245 | - $this->packer = $packer; | ||
246 | - } | ||
247 | - | ||
248 | - /** | ||
249 | - * 注册服务到consul | ||
250 | - * onWorkerStart 和 onStart 回调是在不同进程中并行执行的,不存在先后顺序 | ||
251 | - * | ||
252 | - * @param \Swoole\Server $server | ||
253 | - * @author pengjch 202439 23:11:10 | ||
254 | - */ | ||
255 | - public function onStart(\Swoole\Server $server) | ||
256 | - { | ||
257 | - if ($this->register) { | ||
258 | - $this->logger->info(sprintf('Register server[%s:%d] to %s.', $this->host, $this->port, $this->register->getName())); | ||
259 | - $this->register->register($this->module, $this->host, $this->port, $this->weight); | ||
260 | - } | ||
261 | - } | ||
262 | - | ||
263 | - /** | ||
264 | - * 注销服务 | ||
265 | - * 强制 kill 进程不会回调 onShutdown | ||
266 | - * 需要使用 kill -15 来发送 SIGTERM 信号到主进程才能按照正常的流程终止 | ||
267 | - * | ||
268 | - * @param \Swoole\Server $server | ||
269 | - * @author pengjch 202439 23:14:40 | ||
270 | - */ | ||
271 | - public function onShutdown(\Swoole\Server $server) | ||
272 | - { | ||
273 | - if ($this->register) { | ||
274 | - $this->logger->info(sprintf('UnRegister server[%s:%d] from register.', $this->host, $this->port)); | ||
275 | - $this->register->unRegister($this->host, $this->port); | ||
276 | - } | ||
277 | - } | ||
278 | - | ||
279 | - /** | ||
280 | - * server接收请求 | ||
281 | - * | ||
282 | - * @param \Swoole\Server $server | ||
283 | - * @param $fd | ||
284 | - * @param $reactor_id | ||
285 | - * @param $data | ||
286 | - * @return mixed | ||
287 | - * @author pengjch 202439 11:34:0 | ||
288 | - */ | ||
289 | - public function onReceive(\Swoole\Server $server, $fd, $reactor_id, $data) | ||
290 | - { | ||
291 | - /** @var Request $request */ | ||
292 | - $request = $this->packer->unpack($data); | ||
293 | - //系统请求 | ||
294 | - if ($request->isSystem()) { | ||
295 | - return $server->send($fd, serialize($this->doSystemRequest($request))); | ||
296 | - } | ||
297 | - //同步请求 | ||
298 | - if ($request->isSync()) { | ||
299 | - return $server->send($fd, serialize($this->doRequest($request))); | ||
300 | - } | ||
301 | - //异步请求 | ||
302 | - $server->task($request); | ||
303 | - return $server->send($fd, serialize(Response::success(['result' => 'success']))); | ||
304 | - } | ||
305 | - | ||
306 | - /** | ||
307 | - * 执行请求 | ||
308 | - * | ||
309 | - * @param Request $request | ||
310 | - * @return Response | ||
311 | - * @author pengjch 2024313 9:37:20 | ||
312 | - */ | ||
313 | - public function doRequest(Request $request): Response | ||
314 | - { | ||
315 | - try { | ||
316 | - $handler = $this->getRequestHandler(); | ||
317 | - } catch (\ReflectionException $e) { | ||
318 | - return Response::error($e->getMessage()); | ||
319 | - } | ||
320 | - | ||
321 | - $response = $handler($request); | ||
322 | - if (!($response instanceof Response)) { | ||
323 | - $msg = 'The middleware must return the response type'; | ||
324 | - $this->logger->error($msg); | ||
325 | - $response = Response::error($msg); | ||
326 | - } | ||
327 | - | ||
328 | - return $response; | ||
329 | - } | ||
330 | - | ||
331 | - /** | ||
332 | - * 系统请求 | ||
333 | - * | ||
334 | - * @param Request $request | ||
335 | - * @return Response | ||
336 | - * @author pengjch 2024323 10:46:55 | ||
337 | - */ | ||
338 | - public function doSystemRequest(Request $request): Response | ||
339 | - { | ||
340 | - if ($request->getMethod() == 'stats') { | ||
341 | - return Response::success(['result' => $this->server->stats()]); | ||
342 | - } else { | ||
343 | - return Response::error($request->getMethod() . ' is not supported'); | ||
344 | - } | ||
345 | - } | ||
346 | - | ||
347 | - /** | ||
348 | - * @return mixed | ||
349 | - * @throws \ReflectionException | ||
350 | - * @author pengjch 2024312 16:36:52 | ||
351 | - */ | ||
352 | - public function getRequestHandler() | ||
353 | - { | ||
354 | - return array_reduce(array_reverse($this->middlewares), function ($stack, $next) { | ||
355 | - return function ($request) use ($stack, $next) { | ||
356 | - if ($next instanceof \Closure) { | ||
357 | - return $next($request, $stack); | ||
358 | - } elseif (is_string($next) && class_exists($next)) { | ||
359 | - return (new $next())->handle($request, $stack); | ||
360 | - } else { | ||
361 | - return $next->handle($request, $stack); | ||
362 | - } | ||
363 | - }; | ||
364 | - }, function ($request) { | ||
365 | - return $this->service->call($request); | ||
366 | - }); | ||
367 | - } | ||
368 | - | ||
369 | - /** | ||
370 | - * 异步处理请求 | ||
371 | - * | ||
372 | - * @param $server | ||
373 | - * @param $taskID | ||
374 | - * @param $reactorID | ||
375 | - * @param $data | ||
376 | - * @return Response | ||
377 | - * @author pengjch 2024313 9:40:37 | ||
378 | - */ | ||
379 | - public function OnTask($server, $taskID, $reactorID, $data): Response | ||
380 | - { | ||
381 | - $this->logger->debug('AsyncTask: Start', ['taskID' => $taskID]); | ||
382 | - return $this->doRequest($data); | ||
383 | - } | ||
384 | - | ||
385 | - /** | ||
386 | - * 完成异步任务回调 | ||
387 | - * | ||
388 | - * @param $server | ||
389 | - * @param $taskID | ||
390 | - * @param $data | ||
391 | - * @author pengjch 2024313 9:49:44 | ||
392 | - */ | ||
393 | - public function OnFinish($server, $taskID, $data) | ||
394 | - { | ||
395 | - $this->logger->debug('AsyncTask: Finish', ['taskID' => $taskID, 'data' => $data]); | ||
396 | - } | ||
397 | - | ||
398 | - /** | ||
399 | - * OnClose | ||
400 | - * | ||
401 | - * @param $server | ||
402 | - * @param $fd | ||
403 | - * @author pengjch 202439 11:34:48 | ||
404 | - */ | ||
405 | - public function OnClose($server, $fd) | ||
406 | - { | ||
407 | - $this->logger->debug('Client: Close'); | ||
408 | - } | ||
409 | - | ||
410 | - /** | ||
411 | - * OnConnect | ||
412 | - * | ||
413 | - * @param $server | ||
414 | - * @param $fd | ||
415 | - * @author pengjch 202439 11:34:52 | ||
416 | - */ | ||
417 | - public function OnConnect($server, $fd) | ||
418 | - { | ||
419 | - $this->logger->debug('Client: Connect.'); | ||
420 | - } | ||
421 | - | ||
422 | - /** | ||
423 | - * start | ||
424 | - * | ||
425 | - * @author pengjch 202439 11:34:56 | ||
426 | - */ | ||
427 | - public function start(): bool | ||
428 | - { | ||
429 | - //可用服务数量 | ||
430 | - if ($this->service->count() == 0) { | ||
431 | - $this->logger->error('There is no service available.'); | ||
432 | - return false; | ||
433 | - } | ||
434 | - //默认使用固定包头+包体方式解决粘包问题 | ||
435 | - if (empty($this->packer)) { | ||
436 | - $this->packer = new SerializeLengthPacker([ | ||
437 | - 'package_length_type' => $this->options['package_length_type'] ?? 'N', | ||
438 | - 'package_body_offset' => $this->options['package_body_offset'] ?? 4, | ||
439 | - ]); | ||
440 | - } | ||
441 | - | ||
442 | - $this->logger->info(sprintf('Rpc server[%s:%s] start.', $this->host, $this->port)); | ||
443 | - $this->server->start(); | ||
444 | - return true; | ||
445 | - } | ||
446 | -} |
src/Service.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc; | ||
4 | - | ||
5 | - | ||
6 | -use Psr\Log\LoggerInterface; | ||
7 | -use ReflectionClass; | ||
8 | -use ReflectionMethod; | ||
9 | -use AukeySwrpc\Request\Request; | ||
10 | - | ||
11 | -/** | ||
12 | - * Class Service | ||
13 | - * | ||
14 | - * @package AukeySwrpc | ||
15 | - * @author pengjch 202439 11:39:41 | ||
16 | - */ | ||
17 | -class Service | ||
18 | -{ | ||
19 | - private array $services = []; | ||
20 | - protected array $filers | ||
21 | - = [ | ||
22 | - 'factory', | ||
23 | - 'initTracer', | ||
24 | - 'setModule', | ||
25 | - 'setTracerUrl', | ||
26 | - 'setParams', | ||
27 | - 'setTracerContext', | ||
28 | - 'getTracerContext' | ||
29 | - ]; | ||
30 | - | ||
31 | - /** @var LoggerInterface $logger */ | ||
32 | - private $logger; | ||
33 | - | ||
34 | - public function __construct($logger) | ||
35 | - { | ||
36 | - $this->logger = $logger; | ||
37 | - } | ||
38 | - | ||
39 | - /** | ||
40 | - * 注册服务实例 | ||
41 | - * | ||
42 | - * @param $obj | ||
43 | - * @param $prefix | ||
44 | - * @return bool | ||
45 | - * @author pengjch 202438 13:43:21 | ||
46 | - */ | ||
47 | - public function addInstance($obj, $prefix = ''): bool | ||
48 | - { | ||
49 | - if (is_string($obj)) { | ||
50 | - $obj = new $obj(); | ||
51 | - } | ||
52 | - if (!is_object($obj)) { | ||
53 | - $this->logger->error('Service is not an object.', ['service' => $obj]); | ||
54 | - return false; | ||
55 | - } | ||
56 | - if (!($obj instanceof LogicService)) { | ||
57 | - $this->logger->error('The Service does not inherit LogicService', ['service' => get_class($obj)]); | ||
58 | - return false; | ||
59 | - } | ||
60 | - $className = get_class($obj); | ||
61 | - $methods = get_class_methods($obj); | ||
62 | - foreach ($methods as $method) { | ||
63 | - if (in_array($method, $this->filers)) { | ||
64 | - continue; | ||
65 | - } | ||
66 | - if (strlen($prefix) > 0) { | ||
67 | - $key = $prefix . '_' . $className . '_' . $method; | ||
68 | - } else { | ||
69 | - $key = $className . '_' . $method; | ||
70 | - } | ||
71 | - $this->services[$key] = $className; | ||
72 | - $this->logger->info(sprintf('import %s => %s.', $key, $className)); | ||
73 | - } | ||
74 | - | ||
75 | - return true; | ||
76 | - } | ||
77 | - | ||
78 | - /** | ||
79 | - * 获取服务 | ||
80 | - * | ||
81 | - * @param $key | ||
82 | - * @return mixed|null | ||
83 | - * @author pengjch 202438 13:43:17 | ||
84 | - */ | ||
85 | - public function getService($key) | ||
86 | - { | ||
87 | - return $this->services[$key] ?? null; | ||
88 | - } | ||
89 | - | ||
90 | - /** | ||
91 | - * 获取所有服务 | ||
92 | - * getServices | ||
93 | - * | ||
94 | - * @return array | ||
95 | - * @author pengjch 202438 15:23:58 | ||
96 | - */ | ||
97 | - public function getServices(): array | ||
98 | - { | ||
99 | - return $this->services; | ||
100 | - } | ||
101 | - | ||
102 | - /** | ||
103 | - * count | ||
104 | - * | ||
105 | - * @return int | ||
106 | - * @author pengjch 202439 12:56:46 | ||
107 | - */ | ||
108 | - public function count(): int | ||
109 | - { | ||
110 | - return count($this->services); | ||
111 | - } | ||
112 | - | ||
113 | - /** | ||
114 | - * @param $key | ||
115 | - * @return bool | ||
116 | - * @author pengjch 202438 14:32:50 | ||
117 | - */ | ||
118 | - public function isExist($key): bool | ||
119 | - { | ||
120 | - return isset($this->services[$key]); | ||
121 | - } | ||
122 | - | ||
123 | - /** | ||
124 | - * 调用服务 | ||
125 | - * | ||
126 | - * @param Request $request | ||
127 | - * @return Response | ||
128 | - * @throws \ReflectionException | ||
129 | - * @author pengjch 202439 10:17:59 | ||
130 | - */ | ||
131 | - public function call(Request $request): Response | ||
132 | - { | ||
133 | - if ($err = $request->getError()) { | ||
134 | - return Response::error($err); | ||
135 | - } | ||
136 | - | ||
137 | - $service = $this->getService($request->getMethod()); | ||
138 | - if (!$service) { | ||
139 | - $this->logger->debug('service is not exist.', ['method' => $request->getMethod()]); | ||
140 | - return Response::error('service is not exist.'); | ||
141 | - } | ||
142 | - | ||
143 | - $methodArr = explode('_', $request->getMethod()); | ||
144 | - $methodName = array_pop($methodArr); | ||
145 | - $reflect = new ReflectionClass($service); | ||
146 | - $instance = $reflect->newInstanceArgs(); | ||
147 | - if (!method_exists($instance, $methodName)) { | ||
148 | - $this->logger->debug('method is not exist.', ['method' => $request->getMethod()]); | ||
149 | - return Response::error(sprintf('%s method[%s] is not exist.', $service, $methodName)); | ||
150 | - } | ||
151 | - | ||
152 | - $ctx = $request->getTraceContext(); | ||
153 | - if ($ctx && method_exists($instance, 'setTracerContext')) { | ||
154 | - $instance->setTracerUrl($ctx->getReporterUrl())->setTracerContext($ctx); | ||
155 | - } | ||
156 | - | ||
157 | - try { | ||
158 | - $methodObj = new ReflectionMethod($reflect->getName(), $methodName); | ||
159 | - $result = $methodObj->invokeArgs($instance, $request->getParams()); | ||
160 | - } catch (\Throwable $e) { | ||
161 | - return Response::error($e->getMessage()); | ||
162 | - } | ||
163 | - | ||
164 | - return Response::success([ | ||
165 | - 'result' => $result | ||
166 | - ]); | ||
167 | - } | ||
168 | -} |
src/Tracer/TracerContext.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpc\Tracer; | ||
4 | - | ||
5 | - | ||
6 | -/** | ||
7 | - * 链路追踪上下文 | ||
8 | - * Class TracerContext | ||
9 | - * | ||
10 | - * @package AukeySwrpc\Tracer | ||
11 | - * @author pengjch 2024311 10:21:34 | ||
12 | - */ | ||
13 | -class TracerContext | ||
14 | -{ | ||
15 | - protected $traceID; | ||
16 | - protected $parentID; | ||
17 | - protected $reporterUrl; | ||
18 | - | ||
19 | - public function __construct($traceID, $parentID, $reporterUrl) | ||
20 | - { | ||
21 | - $this->traceID = $traceID; | ||
22 | - $this->parentID = $parentID; | ||
23 | - $this->reporterUrl = $reporterUrl; | ||
24 | - } | ||
25 | - | ||
26 | - public static function create($traceID, $parentID, $reporterUrl) | ||
27 | - { | ||
28 | - return new static($traceID, $parentID, $reporterUrl); | ||
29 | - } | ||
30 | - | ||
31 | - public function setTraceID($traceID) | ||
32 | - { | ||
33 | - $this->traceID = $traceID; | ||
34 | - } | ||
35 | - | ||
36 | - public function setParentID($parentID) | ||
37 | - { | ||
38 | - $this->parentID = $parentID; | ||
39 | - } | ||
40 | - | ||
41 | - public function setReporterUrl($url) | ||
42 | - { | ||
43 | - $this->reporterUrl = $url; | ||
44 | - } | ||
45 | - | ||
46 | - public function getTraceID() | ||
47 | - { | ||
48 | - return $this->traceID; | ||
49 | - } | ||
50 | - | ||
51 | - public function getParentID() | ||
52 | - { | ||
53 | - return $this->parentID; | ||
54 | - } | ||
55 | - | ||
56 | - public function getReporterUrl() | ||
57 | - { | ||
58 | - return $this->reporterUrl; | ||
59 | - } | ||
60 | -} |
tests/BootTest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests; | ||
4 | - | ||
5 | - | ||
6 | -use PHPUnit\Framework\TestCase; | ||
7 | - | ||
8 | -/** | ||
9 | - * Class BootTest | ||
10 | - * | ||
11 | - * @author wuzhc | ||
12 | - * @internal | ||
13 | - */ | ||
14 | -abstract class BootTest extends TestCase | ||
15 | -{ | ||
16 | - const PID_FILE = __DIR__ . '/AukeySwrpc.pid'; | ||
17 | - const SERVER_LOG = __DIR__ . '/AukeySwrpc.log'; | ||
18 | - const SERVER_SCRIPT = __DIR__ . '/server.sh'; | ||
19 | - | ||
20 | - public static function setUpBeforeClass(): void | ||
21 | - { | ||
22 | - // fwrite(STDOUT, 'Starting rpc server...' . PHP_EOL); | ||
23 | - $cmd = 'nohup ' . self::SERVER_SCRIPT . ' > ' . self::SERVER_LOG . ' 2>&1 &'; | ||
24 | - shell_exec($cmd); | ||
25 | - sleep(5); | ||
26 | - | ||
27 | - self::assertFileExists(self::PID_FILE, 'Run rpc server failed: ' . $cmd . ''); | ||
28 | - $pid = file_get_contents(self::PID_FILE); | ||
29 | - self::assertNotEmpty($pid, 'Failed to start the rpc server.'); | ||
30 | - | ||
31 | - $res = shell_exec('ps aux | grep ' . $pid . ' | wc -l'); | ||
32 | - self::assertGreaterThanOrEqual(1, intval($res), 'Failed to start the rpc server.'); | ||
33 | - | ||
34 | - // fwrite(STDOUT, 'Rpc server started successfully.' . PHP_EOL); | ||
35 | - } | ||
36 | - | ||
37 | - public static function tearDownAfterClass(): void | ||
38 | - { | ||
39 | - if (\file_exists(self::PID_FILE)) { | ||
40 | - $pid = file_get_contents(self::PID_FILE); | ||
41 | - \shell_exec('kill -15 ' . $pid); | ||
42 | - if (\file_exists(self::PID_FILE)) { | ||
43 | - \unlink(self::PID_FILE); | ||
44 | - } | ||
45 | - \sleep(1); | ||
46 | - } | ||
47 | - } | ||
48 | -} |
tests/ClientTest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Register\Consul; | ||
7 | -use AukeySwrpc\Register\Service; | ||
8 | -use AukeySwrpc\Request; | ||
9 | -use AukeySwrpc\Client; | ||
10 | - | ||
11 | -/** | ||
12 | - * 客户端单元测试 | ||
13 | - * php74 ../phpunit.phar tests/ClientTest.php --debug | ||
14 | - * Class ClientTest | ||
15 | - * | ||
16 | - * @link http://www.phpunit.cn/manual/7.0/zh_cn/index.html | ||
17 | - * @author pengjch 2024312 9:39:22 | ||
18 | - */ | ||
19 | -class ClientTest extends BootTest | ||
20 | -{ | ||
21 | - /** | ||
22 | - * @return Client Client | ||
23 | - * @author pengjch 2024312 14:29:28 | ||
24 | - */ | ||
25 | - public function testClientConnect(): Client | ||
26 | - { | ||
27 | - $client = Client::create('School_Module', getenv('RPC_SERVER_HOST'), getenv('RPC_SERVER_PORT')); | ||
28 | - $conn = $client->connect(); | ||
29 | - $this->assertIsBool($conn->isConnected(), 'Client connect failure.'); | ||
30 | - return $client; | ||
31 | - } | ||
32 | - | ||
33 | - /** | ||
34 | - * @depends testClientConnect | ||
35 | - * @param Client $client | ||
36 | - * @author pengjch 2024312 14:29:20 | ||
37 | - */ | ||
38 | - public function testClientSyncRequest($client) | ||
39 | - { | ||
40 | - $request = Request\SyncRequest::create('AukeySwrpcTests\services\SchoolService_getUserSchool', [1, 1]); | ||
41 | - $res = $client->send($request); | ||
42 | - $this->assertEquals('未来学校1', $res); | ||
43 | - } | ||
44 | - | ||
45 | - /** | ||
46 | - * @depends testClientConnect | ||
47 | - * @param $client | ||
48 | - * @author pengjch 2024313 10:3:43 | ||
49 | - */ | ||
50 | - public function testClientAsyncRequest($client) | ||
51 | - { | ||
52 | - $request = Request\AsyncRequest::create('AukeySwrpcTests\services\SchoolService_saveUserName', ['tony']); | ||
53 | - $res = $client->send($request); | ||
54 | - $this->assertEquals('success', $res); | ||
55 | - sleep(3); | ||
56 | - $this->assertFileExists('xxx.log', 'Async request failure.'); | ||
57 | - $value = file_get_contents('xxx.log'); | ||
58 | - $this->assertEquals('tony', $value); | ||
59 | - @unlink('xxx.log'); | ||
60 | - } | ||
61 | -} |
tests/PackerTest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests; | ||
4 | - | ||
5 | - | ||
6 | -use PHPUnit\Framework\TestCase; | ||
7 | -use AukeySwrpc\Request\SyncRequest; | ||
8 | - | ||
9 | -/** | ||
10 | - * Class PackerTest | ||
11 | - * php74 ../phpunit.phar tests/ClientTest.php | ||
12 | - * | ||
13 | - * @package AukeySwrpcTests | ||
14 | - * @author pengjch 2024312 16:5:14 | ||
15 | - */ | ||
16 | -class PackerTest extends TestCase | ||
17 | -{ | ||
18 | - /** | ||
19 | - * 注意:Request类属性和方法发生变化时,这个测试案例就没有意义了 | ||
20 | - * @return string | ||
21 | - * @author pengjch 2024312 14:57:32 | ||
22 | - */ | ||
23 | - public function testSerializeLengthPack() | ||
24 | - { | ||
25 | - $packer = new \AukeySwrpc\Packer\SerializeLengthPacker(); | ||
26 | - $result = $packer->pack(SyncRequest::create('SchoolService_getName', [1, 1])); | ||
27 | - $this->assertEquals('AAAAzU86MjU6IlN3cnBjXFJlcXVlc3RcU3luY1JlcXVlc3QiOjY6e3M6OToiACoAbWV0aG9kIjtzOjIxOiJTY2hvb2xTZXJ2aWNlX2dldE5hbWUiO3M6OToiACoAcGFyYW1zIjthOjI6e2k6MDtpOjE7aToxO2k6MTt9czo5OiIAKgBpc1N5bmMiO2I6MTtzOjExOiIAKgBpc1N5c3RlbSI7YjowO3M6ODoiACoAZXJyb3IiO047czoxNToiACoAdHJhY2VDb250ZXh0IjtOO30=', base64_encode($result)); | ||
28 | - return base64_encode($result); | ||
29 | - } | ||
30 | - | ||
31 | - /** | ||
32 | - * @depends testSerializeLengthPack | ||
33 | - * @author pengjch 2024312 14:57:23 | ||
34 | - */ | ||
35 | - public function testSerializeLenghtUnpack($value) | ||
36 | - { | ||
37 | - $expect = SyncRequest::create('SchoolService_getName', [1, 1]); | ||
38 | - $packer = new \AukeySwrpc\Packer\SerializeLengthPacker(); | ||
39 | - $result = $packer->unpack(base64_decode($value)); | ||
40 | - $this->assertSame(serialize($expect), serialize($result)); | ||
41 | - } | ||
42 | - | ||
43 | - /** | ||
44 | - * 注意:Request类属性和方法发生变化时,这个测试案例就没有意义了 | ||
45 | - * @return string | ||
46 | - * @author pengjch 2024312 14:57:32 | ||
47 | - */ | ||
48 | - public function testSerializeEofPack() | ||
49 | - { | ||
50 | - $packer = new \AukeySwrpc\Packer\SerializeEofPacker(); | ||
51 | - $result = $packer->pack(SyncRequest::create('SchoolService_getName', [1, 1])); | ||
52 | - $this->assertEquals('TzoyNToiU3dycGNcUmVxdWVzdFxTeW5jUmVxdWVzdCI6Njp7czo5OiIAKgBtZXRob2QiO3M6MjE6IlNjaG9vbFNlcnZpY2VfZ2V0TmFtZSI7czo5OiIAKgBwYXJhbXMiO2E6Mjp7aTowO2k6MTtpOjE7aToxO31zOjk6IgAqAGlzU3luYyI7YjoxO3M6MTE6IgAqAGlzU3lzdGVtIjtiOjA7czo4OiIAKgBlcnJvciI7TjtzOjE1OiIAKgB0cmFjZUNvbnRleHQiO047fQ==', base64_encode($result)); | ||
53 | - return base64_encode($result); | ||
54 | - } | ||
55 | - | ||
56 | - /** | ||
57 | - * @depends testSerializeEofPack | ||
58 | - * @author pengjch 2024312 14:57:23 | ||
59 | - */ | ||
60 | - public function testSerializeEofUnpack($value) | ||
61 | - { | ||
62 | - $expect = SyncRequest::create('SchoolService_getName', [1, 1]); | ||
63 | - $packer = new \AukeySwrpc\Packer\SerializeEofPacker(); | ||
64 | - $result = $packer->unpack(base64_decode($value)); | ||
65 | - $this->assertSame(serialize($expect), serialize($result)); | ||
66 | - } | ||
67 | -} |
tests/ServerTest.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests; | ||
4 | - | ||
5 | - | ||
6 | -use Monolog\Logger; | ||
7 | -use AukeySwrpc\Register\Consul; | ||
8 | -use AukeySwrpc\Register\Service; | ||
9 | -use AukeySwrpc\Request\Request; | ||
10 | -use AukeySwrpc\Request\SyncRequest; | ||
11 | -use AukeySwrpc\Server; | ||
12 | -use AukeySwrpcTests\services\UserService; | ||
13 | - | ||
14 | -/** | ||
15 | - * Class ServerTest | ||
16 | - * php74 ../phpunit.phar tests/ClientTest.php | ||
17 | - * | ||
18 | - * @package AukeySwrpcTests | ||
19 | - * @author pengjch 2024312 16:5:7 | ||
20 | - */ | ||
21 | -class ServerTest extends \PHPUnit\Framework\TestCase | ||
22 | -{ | ||
23 | - /** | ||
24 | - * @author pengjch 2024312 17:8:31 | ||
25 | - */ | ||
26 | - public function testServerRegisterToConsul() | ||
27 | - { | ||
28 | - $res = shell_exec('netstat anp | grep ' . getenv('CONSUL_PORT') . ' | wc -l'); | ||
29 | - $this->assertGreaterThanOrEqual(1, intval($res), 'Warning: Consul not started.'); | ||
30 | - | ||
31 | - $consul = new Consul('http://' . getenv('CONSUL_HOST') . ':' . getenv('CONSUL_PORT')); | ||
32 | - $consul->register('test_module', '127.0.0.1', 8080); | ||
33 | - | ||
34 | - $isSuccess = false; | ||
35 | - $services = $consul->getServices('test_module'); | ||
36 | - /** @var Service $service */ | ||
37 | - foreach ($services as $service) { | ||
38 | - if ($service->getHost() == '127.0.0.1' && $service->getPort() == 8080) { | ||
39 | - $isSuccess = true; | ||
40 | - break; | ||
41 | - } | ||
42 | - } | ||
43 | - | ||
44 | - $this->assertIsBool($isSuccess); | ||
45 | - return $consul; | ||
46 | - } | ||
47 | - | ||
48 | - /** | ||
49 | - * @depends testServerRegisterToConsul | ||
50 | - * @param Consul $consul | ||
51 | - * @author pengjch 2024312 17:12:17 | ||
52 | - */ | ||
53 | - public function testServerUnregisterFromConsul($consul) | ||
54 | - { | ||
55 | - $consul->unRegister('127.0.0.1', 8080); | ||
56 | - $isSuccess = true; | ||
57 | - $services = $consul->getServices('test_module'); | ||
58 | - /** @var Service $service */ | ||
59 | - foreach ($services as $service) { | ||
60 | - if ($service->getHost() == '127.0.0.1' && $service->getPort() == 8080) { | ||
61 | - $isSuccess = false; | ||
62 | - break; | ||
63 | - } | ||
64 | - } | ||
65 | - $this->assertIsBool($isSuccess); | ||
66 | - } | ||
67 | - | ||
68 | - /** | ||
69 | - * @return Server | ||
70 | - * @author pengjch 2024312 17:8:17 | ||
71 | - */ | ||
72 | - public function testServerAddService() | ||
73 | - { | ||
74 | - $logger = new Logger('swprc'); | ||
75 | - $server = new Server('School_Module', getenv('RPC_SERVER_HOST'), getenv('RPC_SERVER_PORT'), [], null, null, $logger); | ||
76 | - $server->addService(UserService::class); | ||
77 | - $key = UserService::class . '_getName'; | ||
78 | - $value = $server->getService($key); | ||
79 | - $this->assertEquals(UserService::class, $value); | ||
80 | - return $server; | ||
81 | - } | ||
82 | - | ||
83 | - /** | ||
84 | - * @depends testServerAddService | ||
85 | - * @param $server | ||
86 | - * @author pengjch 2024312 16:40:0 | ||
87 | - */ | ||
88 | - public function testServerAddMiddleware($server) | ||
89 | - { | ||
90 | - $request = SyncRequest::create('AukeySwrpcTests\services\UserService_getFavoriteFood', ['肥胖']); | ||
91 | - $server->addMiddleware(function (Request $request, $next) { | ||
92 | - $request->setParams(['帅气']); | ||
93 | - return $next($request); | ||
94 | - }); | ||
95 | - $func = $server->getRequestHandler(); | ||
96 | - $result = $func($request); | ||
97 | - $this->assertEquals('帅气的我喜欢吃苹果', $result->data['result']); | ||
98 | - } | ||
99 | -} |
tests/server.sh
已删除
100755 → 0
1 | -#!/usr/bin/env /opt/php74/bin/php | ||
2 | -<?php | ||
3 | - | ||
4 | -use AukeySwrpc\Register\Consul; | ||
5 | -use AukeySwrpc\Server; | ||
6 | - | ||
7 | -$basePath = dirname(dirname(__FILE__)); | ||
8 | -require_once $basePath . "/vendor/autoload.php"; | ||
9 | - | ||
10 | -$options = [ | ||
11 | - 'enable_coroutine' => true, | ||
12 | - 'pid_file' => __DIR__ . '/AukeySwrpc.pid', | ||
13 | -]; | ||
14 | -$server = new Server('School_Module', getenv('RPC_SERVER_HOST'), getenv('RPC_SERVER_PORT'), $options); | ||
15 | -$server->addRegister(new Consul()) | ||
16 | - ->addService(\AukeySwrpcTests\services\UserService::class) | ||
17 | - ->addService(\AukeySwrpcTests\services\SchoolService::class) | ||
18 | - ->addService(\AukeySwrpcTests\services\ClassService::class) | ||
19 | - ->start(); |
tests/services/ClassService.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests\services; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Exceptions\RpcException; | ||
7 | -use AukeySwrpc\LogicService; | ||
8 | -use AukeySwrpc\Register\Consul; | ||
9 | -use AukeySwrpc\Request\SyncRequest; | ||
10 | - | ||
11 | -/** | ||
12 | - * Class ClassService | ||
13 | - * | ||
14 | - * @package AukeySwrpcTests\services | ||
15 | - * @author pengjch 2024313 9:15:21 | ||
16 | - */ | ||
17 | -class ClassService extends LogicService | ||
18 | -{ | ||
19 | - public function getUserClass($userID = 1): string | ||
20 | - { | ||
21 | - $register = new Consul(); | ||
22 | - try { | ||
23 | - $classID = 111; | ||
24 | - $client = \AukeySwrpc\Client::createBalancer('School_Module', $register, \AukeySwrpc\Client::STRATEGY_WEIGHT); | ||
25 | - $result = $client->send(SyncRequest::create('SchoolService_getUserSchool', [ | ||
26 | - $userID, | ||
27 | - $classID, | ||
28 | - ], $this->getTracerContext(__FUNCTION__))); | ||
29 | - } catch (RpcException $e) { | ||
30 | - return $e->getMessage() . PHP_EOL; | ||
31 | - } | ||
32 | - | ||
33 | - return '高一2班, school:' . $result; | ||
34 | - } | ||
35 | -} |
tests/services/SchoolService.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests\services; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\LogicService; | ||
7 | - | ||
8 | -/** | ||
9 | - * Class SchoolService | ||
10 | - * | ||
11 | - * @package AukeySwrpcTests\services | ||
12 | - * @author pengjch 2024313 9:15:30 | ||
13 | - */ | ||
14 | -class SchoolService extends LogicService | ||
15 | -{ | ||
16 | - public function getUserSchool($userID, $classID): string | ||
17 | - { | ||
18 | - return '未来学校' . $userID; | ||
19 | - } | ||
20 | - | ||
21 | - public function saveUserName($name) | ||
22 | - { | ||
23 | - file_put_contents('xxx.log', $name); | ||
24 | - } | ||
25 | -} |
tests/services/UserService.php
已删除
100755 → 0
1 | -<?php | ||
2 | - | ||
3 | -namespace AukeySwrpcTests\services; | ||
4 | - | ||
5 | - | ||
6 | -use AukeySwrpc\Exceptions\RpcException; | ||
7 | -use AukeySwrpc\LogicService; | ||
8 | -use AukeySwrpc\Register\Consul; | ||
9 | -use AukeySwrpc\Request\SyncRequest; | ||
10 | - | ||
11 | -/** | ||
12 | - * Class UserService | ||
13 | - * | ||
14 | - * @package AukeySwrpcTests\services | ||
15 | - * @author pengjch 2024313 9:15:52 | ||
16 | - */ | ||
17 | -class UserService extends LogicService | ||
18 | -{ | ||
19 | - /** | ||
20 | - * @return UserService | ||
21 | - * @author pengjch 2024311 11:32:35 | ||
22 | - */ | ||
23 | - public static function factory() | ||
24 | - { | ||
25 | - return parent::factory(); | ||
26 | - } | ||
27 | - | ||
28 | - public function getName(): string | ||
29 | - { | ||
30 | - $register = new Consul(); | ||
31 | - try { | ||
32 | - $userID = 1; | ||
33 | - $client = \AukeySwrpc\Client::createBalancer('Class_Module', $register, \AukeySwrpc\Client::STRATEGY_WEIGHT); | ||
34 | - $result = $client->send(SyncRequest::create('ClassService_getUserClass', [$userID], $this->getTracerContext(__FUNCTION__))); | ||
35 | - } catch (RpcException $e) { | ||
36 | - return $e->getMessage() . PHP_EOL; | ||
37 | - } | ||
38 | - | ||
39 | - return 'user:wuzhc, class:' . $result; | ||
40 | - } | ||
41 | - | ||
42 | - public function getAge(): int | ||
43 | - { | ||
44 | - return 30; | ||
45 | - } | ||
46 | - | ||
47 | - public function getFavoriteFood($prefix) | ||
48 | - { | ||
49 | - return $prefix . '的我喜欢吃苹果'; | ||
50 | - } | ||
51 | -} |
-
请 注册 或 登录 后发表评论