这篇文章主要介绍“Swoft 2.0.6怎么实现Rpc服务客户端以及非Swoft框架外部调用”,在日常操作中,相信很多人在Swoft 2.0.6怎么实现Rpc服务客户端以及非Swoft框架外部调用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Swoft 2.0.6怎么实现Rpc服务客户端以及非Swoft框架外部调用”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
1.首先启动http跟rpc服务。
我这里是直接用docker-compose开启服务的。
大家也可以进入swoft容器用命令开启服务。
http命令:php bin/swoft http:start
rpc命令:php bin/swoft rpc:start
2.RPC Server 配置参数
RPC 服务启动有单独启动和集成其它服务(Http/Websocket)两种方式,无论那种方式都首先要在 bean.php 配置RPC。
'rpcServer' => [
'class' => ServiceServer::class,
'port' => 18307,
],
3.Http server 启动中集成 RPC 服务,其listener 单独监听一个RPC服务,且同时可以监听多个 RPC 服务中
'httpServer' => [
'class' => HttpServer::class,
'port' => 18306,
'listener' => [
'rpc' => bean('rpcServer')
],
'process' => [
// 'monitor' => bean(MonitorProcess::class)
// 'crontab' => bean(CrontabProcess::class)
],
'on' => [
// SwooleEvent::TASK => bean(SyncTaskListener::class), // Enable sync task
SwooleEvent::TASK => bean(TaskListener::class), // Enable task must task and finish event
SwooleEvent::FINISH => bean(FinishListener::class)
],
/* @see HttpServer::$setting */
'setting' => [
'task_worker_num' => 12,
'task_enable_coroutine' => true,
'worker_num' => 6
]
],
5.定义接口并实现接口,才能提供RPC服务。注意里面的版本号定制注解@Service()
6.定义接口
<?php declare(strict_types=1);
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://swoft.org/docs
* @contact group@swoft.org
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace App\Rpc\Service;
use App\Rpc\Lib\UserInterface;
use Exception;
use Swoft\Co;
use Swoft\Rpc\Server\Annotation\Mapping\Service;
/**
* Class UserService
*
* @since 2.0
*
* @Service()
*/
class UserService implements UserInterface
{
/**
* @param int $id
* @param mixed $type
* @param int $count
*
* @return array
*/
public function getList(int $id, $type, int $count = 10): array
{
return ['name' => ['list']];
}
/**
* @param int $id
*
* @return bool
*/
public function delete(int $id): bool
{
return false;
}
/**
* @return void
*/
public function returnNull(): void
{
return;
}
/**
* @return string
*/
public function getBigContent(): string
{
$content = Co::readFile(__DIR__ . '/big.data');
return $content;
}
/**
* Exception
* @throws Exception
*/
public function exception(): void
{
throw new Exception('exception version');
}
/**
* @param string $content
*
* @return int
*/
public function sendBigContent(string $content): int
{
return strlen($content);
}
}
7.按版本实现不同的接口需求
/**
* Class UserService
*
* @since 2.0
*
* @Service()
*/
/**
* Class UserServiceV2
*
* @since 2.0
*
* @Service(version="1.2")
*/
不同的实现,需要定义不同的唯一版本号,如果存在相同,加载之后的服务会覆盖之前的服务
8.RPC Client配置参数
同样也是在bean.php中配置,如以下是一个user 服务
'user' => [
'class' => ServiceClient::class,
'host' => '127.0.0.1',
'port' => 18307,
'setting' => [
'timeout' => 0.5,
'connect_timeout' => 1.0,
'write_timeout' => 10.0,
'read_timeout' => 0.5,
],
'packet' => bean('rpcClientPacket')
],
'user.pool' => [
'class' => ServicePool::class,
'client' => bean('user'),
],
8.客户调用
<?php declare(strict_types=1);
/**
* This file is part of Swoft.
*
* @link https://swoft.org
* @document https://swoft.org/docs
* @contact group@swoft.org
* @license https://github.com/swoft-cloud/swoft/blob/master/LICENSE
*/
namespace App\Http\Controller;
use App\Rpc\Lib\UserInterface;
use Exception;
use Swoft\Co;
use Swoft\Exception\SwoftException;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
use Swoft\Rpc\Client\Annotation\Mapping\Reference;
/**
* Class RpcController
*
* @since 2.0
*
* @Controller()
*/
class RpcController
{
/**
* @Reference(pool="user.pool")
*
* @var UserInterface
*/
private $userService;
/**
* @Reference(pool="user.pool", version="1.2")
*
* @var UserInterface
*/
private $userService2;
/**
* @RequestMapping("getList")
*
* @return array
*/
public function getList(): array
{
$result = $this->userService->getList(12, 'type');
$result2 = $this->userService2->getList(12, 'type');
return [$result, $result2];
}
/**
* @RequestMapping("returnBool")
*
* @return array
*/
public function returnBool(): array
{
$result = $this->userService->delete(12);
if (is_bool($result)) {
return ['bool'];
}
return ['notBool'];
}
/**
* @RequestMapping()
*
* @return array
*/
public function bigString(): array
{
$string = $this->userService->getBigContent();
return ['string', strlen($string)];
}
/**
* @RequestMapping()
*
* @return array
* @throws SwoftException
*/
public function sendBigString(): array
{
$content = Co::readFile(__DIR__ . '/../../Rpc/Service/big.data');
$len = strlen($content);
$result = $this->userService->sendBigContent($content);
return [$len, $result];
}
/**
* @RequestMapping()
*
* @return array
*/
public function returnNull(): array
{
$this->userService->returnNull();
return [null];
}
/**
* @RequestMapping()
*
* @return array
*
* @throws Exception
*/
public function exception(): array
{
$this->userService->exception();
return ['exception'];
}
}
9.地址栏访问效果。
我这里的ip是自己http服务的ip,大家根据自己的实际修改即可。
10.如何实现非Swoft框架调用
需要注意swoft框架的默认消息协议是json-rpc,而且默认消息协议是以 \r\n\r\n
结尾的。
其他框架代码例子如下,可以自行封装:
<?php
const RPC_EOL = "\r\n\r\n";
function request($host, $class, $method, $param, $version = '1.0', $ext = []) {
$fp = stream_socket_client($host, $errno, $errstr);
if (!$fp) {
throw new Exception("stream_socket_client fail errno={$errno} errstr={$errstr}");
}
$req = [
"jsonrpc" => '2.0',
"method" => sprintf("%s::%s::%s", $version, $class, $method),
'params' => $param,
'id' => '',
'ext' => $ext,
];
$data = json_encode($req) . RPC_EOL;
fwrite($fp, $data);
$result = '';
while (!feof($fp)) {
$tmp = stream_socket_recvfrom($fp, 1024);
if ($pos = strpos($tmp, RPC_EOL)) {
$result .= substr($tmp, 0, $pos);
break;
} else {
$result .= $tmp;
}
}
fclose($fp);
return json_decode($result, true);
}
$ret = request('tcp://172.18.0.6:18307', \App\Rpc\Lib\UserInterface::class, 'getList', [1, 2], "1.2");
var_dump($ret);
11.需要格外注意是框架外调用的ip地址并非官方文档例子里的127.0.0.1,大家改为自己的实际ip即可。不然会连接报错。
到此,关于“Swoft 2.0.6怎么实现Rpc服务客户端以及非Swoft框架外部调用”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/u/4228709/blog/3115858