服務(wù)端的實現(xiàn)基于 workman。
使用 stream_socket_*
實現(xiàn)了一個簡單的同步 client ,目前只支持 workman 的 frame 協(xié)議。
使用示例:https://github.com/caylof/php-rpc
服務(wù)方法的定義需要遵循如下方式函數(shù)簽名:
function (array | Google\Protobuf\Internal\Message $request): array | Google\Protobuf\Internal\Message
composer require caylof/rpc
process/RpcServer.php
<?php
namespace process;
use Caylof\Rpc\Driver\WorkmanServer;
use Caylof\Rpc\ServiceCaller;
use Caylof\Rpc\ServiceRepository;
use support\Container;
class RpcServer extends WorkmanServer
{
public function __construct()
{
$container = Container::instance();
$serviceCaller = new ServiceCaller();
$serviceCaller->setCallerRegistry(new ServiceRepository($container));
$this->setServiceCaller($serviceCaller);
}
}
config/process.php
添加進(jìn)程'rpc' => [
'handler' => process\RpcServer::class,
'listen' => 'frame://0.0.0.0:2345',
'count' => 1,
],
定義一個服務(wù)
新建文件 app/rpc/TestSrv
:
<?php
namespace app\rpc;
class TestSrv
{
public function hello(array $request): array
{
$name = $request['name'] ?? 'ctv';
return ['msg' => 'hello ' . $name];
}
}
重啟 webman 完成服務(wù)端 server
proto user worker listen processes status
tcp root webman http://0.0.0.0:8787 1 [OK]
tcp root monitor none 1 [OK]
tcp root rpc frame://0.0.0.0:2345 1 [OK]
client 端調(diào)用
這里為簡便,可以直接在 controller
中 測試,在 IndexController
中 添加一個 action
:
public function rpc()
{
$client = new \Caylof\Rpc\Driver\WorkmanFrameClient('tcp', '127.0.0.1', 2345);
$result = $client->call('app\\rpc\\TestSrv@hello', ['name' => 'asdf']);
return json($result);
}
然后訪問 http://127.0.0.1:8787/index/rpc
,不出意外應(yīng)該會調(diào)用成功。
client 進(jìn)一步封裝
新建文件 app/rpc/client/ServiceClient.php
,作為一個客戶端的基類:
<?php
namespace app\rpc\client;
use Caylof\Rpc\Driver\WorkmanFrameClient;
abstract class ServiceClient
{
protected WorkmanFrameClient $client;
protected string $serverServicePrefix = 'app\\rpc';
public function __construct()
{
$this->client = new WorkmanFrameClient('tcp', '127.0.0.1', 2345);
}
public function __call(string $name, array $arguments)
{
$caller = sprintf('%s\\%s@%s',
trim($this->serverServicePrefix, '\\'),
substr(static::class, strrpos(static::class, '\\') + 1),
$name
);
return $this->client->call($caller, ...$arguments);
}
}
新建文件 app/rpc/client/TestSrv.php
,作為 client 端服務(wù)類,只需繼續(xù)基類:
<?php
namespace app\rpc\client;
class TestSrv extends ServiceClient
{
}
使用 client 服務(wù)類調(diào)用:
$srv = new \app\rpc\client\TestSrv();
$result = $srv->hello(['name' => 'asdf']);
over~ 感謝 workman !!!
http://www.wtbis.cn/q/6057 其實這個一樣的簡單