服务端的实现基于 workman。
使用 stream_socket_*
实现了一个简单的同步 client ,目前只支持 workman 的 frame 协议。
使用示例:https://github.com/caylof/php-rpc
服务方法的定义需要遵循如下方式函数签名:
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
添加进程'rpc' => [
'handler' => process\RpcServer::class,
'listen' => 'frame://0.0.0.0:2345',
'count' => 1,
],
定义一个服务
新建文件 app/rpc/TestSrv
:
<?php
namespace app\rpc;
class TestSrv
{
public function hello(array $request): array
{
$name = $request['name'] ?? 'ctv';
return ['msg' => 'hello ' . $name];
}
}
重启 webman 完成服务端 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 端调用
这里为简便,可以直接在 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
,不出意外应该会调用成功。
client 进一步封装
新建文件 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 端服务类,只需继续基类:
<?php
namespace app\rpc\client;
class TestSrv extends ServiceClient
{
}
使用 client 服务类调用:
$srv = new \app\rpc\client\TestSrv();
$result = $srv->hello(['name' => 'asdf']);
over~ 感谢 workman !!!
https://www.workerman.net/q/6057 其实这个一样的简单
坏了,确确实实是在大佬面前班门弄斧了
之前群主就弄的 不过多一个选择也没有错
这是啥,云函数吗