官方项目地址https://github.com/top-think/think-swoolephp
tp官方的think-swoole扩展提供了一个rpc服务和客户端,可是他的rpc客户端只能在swoole的环境下运行git
可是swoole官方是提供了同步客户端/swoole/client的,若是把框架的client更换成官方的同步client,应该就能实如今传统的fpm环境中调用swoole环境下的rpc。github
<?php namespace appservice; use Exception; use Generator; use SwooleClient; use SwooleCoroutine; use thinkhelperArr; use thinkService; use thinkswooleexceptionRpcClientException; use thinkswoolePool; use thinkswoolerpcclientConnector; use thinkswoolerpcclientGateway; use thinkswoolerpcclientProxy; use thinkswoolerpcJsonParser; use thinkswoolerpcPacker; use Throwable; class SwooleRpcServiceLoad extends Service { public $rpcServices = []; /** * 注册服务 * * @return mixed */ public function register() { if (php_sapi_name() == 'fpm-fcgi') { if (file_exists($rpc = $this->app->getBasePath() . 'rpc.php')) { $this->rpcServices = (array)include $rpc; } } } /** * 执行服务 * * @return mixed */ public function boot() { if (!empty($clients = config('swoole.rpc.client')) && $this->rpcServices) { try { foreach ($this->rpcServices as $name => $abstracts) { $parserClass = config("swoole.rpc.client.{$name}.parser", JsonParser::class); $parser = $this->app->make($parserClass); $gateway = new Gateway($this->createRpcConnector($name), $parser); foreach ($abstracts as $abstract) { $this->app->bind($abstract, function () use ($gateway, $name, $abstract) { return $this->app->invokeClass(Proxy::getClassName($name, $abstract), [$gateway]); }); } } } catch (Exception | Throwable $e) { } } } protected function createRpcConnector($name) { return new class($name) implements Connector { public $name; public function __construct($name) { $this->name = $name; } public function sendAndRecv($data) { if (!$data instanceof Generator) { $data = [$data]; } $config = config('swoole.rpc.client.' . $this->name); $client = new Client(SWOOLE_SOCK_TCP); $host = Arr::pull($config, 'host'); $port = Arr::pull($config, 'port'); $timeout = Arr::pull($config, 'timeout', 5); $client->set([ 'open_length_check' => true, 'package_length_type' => Packer::HEADER_PACK, 'package_length_offset' => 0, 'package_body_offset' => 8, ]); $client->connect($host, $port, $timeout); try { foreach ($data as $string) { if (!$client->send($string)) { $this->onError($client); } } $response = $client->recv(); if ($response === false || empty($response)) { $this->onError($client); } return $response; } finally { $client->close(); } } protected function onError(Client $client) { $client->close(); throw new RpcClientException(swoole_strerror($client->errCode), $client->errCode); } }; } }
把上面这个服务在thinkphp框架中注册,就能够实如今fpm环境下调用think-swoole的rpc。
原理就是检测当前是否在fpm环境,是的话手动注册rpc服务,官方的扩展是要使用php think swoole start命令启动时,才能在代码中访问rpc接口的,注册了这个服务之后,就能够在fpm环境下使用了,而且不影响其余功能。thinkphp
区别:
1官方扩展使用的是链接池,这里去掉了。
2官方扩展使用的是协程客户端,这里使用的是同步客户端api
用法:
跟官方一致php框架