Hyperf-JsonRpc使用
標簽(空格分隔): php
安裝擴展包
composer require hyperf/json-rpc
composer require hyperf/rpc-server
composer require hyperf/rpc-client
使用
服務有兩種角色,一種是 服務提供者(ServiceProvider),即為其它服務提供服務的服務,另一種是 服務消費者(ServiceConsumer),即依賴其它服務的服務,一個服務既可能是 服務提供者(ServiceProvider),同時又是 服務消費者(ServiceConsumer)。而兩者直接可以通過 服務契約 來定義和約束接口的調用,在 Hyperf 里,可直接理解為就是一個 接口類(Interface),通常來說這個接口類會同時出現在提供者和消費者下。
server.php
servers 下增加配置
// jsonrpc-http 服務配置
[
'name' => 'jsonrpc-http',
'type' => Server::SERVER_HTTP,
'host' => '0.0.0.0',
'port' => 9504,
'sock_type' => SWOOLE_SOCK_TCP,
'callbacks' => [
Event::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'],
],
],
services.php 標記要從何服務中心或者哪個節點 獲取節點信息,服務中心配起來很麻煩
<?php
return [
'consumers' => [
[
// 對應消費者類的 $serviceName
'name' => 'UserServiceServer',
// 這個消費者要從哪個服務中心獲取節點信息,如不配置則不會從服務中心獲取節點信息
// 'registry' => [
// 'protocol' => 'consul',
// 'address' => 'http://127.0.0.1:8500',
// ],
// 如果沒有指定上面的 registry 配置,即為直接對指定的節點進行消費,通過下面的 nodes 參數來配置服務提供者的節點信息
'nodes' => [
['host' => '127.0.0.1', 'port' => 9504],
],
]
],
];
目錄結構
定義Server端來提供服務
// 定義接口,更加規范
<?php
declare(strict_types=1);
namespace App\Rpc\Inter;
interface UserServiceInter
{
public function getUserInfo(int $userId) : string;
public function getUserList(int $page, int $pageSize, array $params = []) : string;
}
// server
<?php
declare(strict_types=1);
namespace App\Rpc\Server;
use App\Rpc\Inter\UserServiceInter;
use App\Utils\ResJson;
use Hyperf\Di\Annotation\Inject;
use Hyperf\RpcServer\Annotation\RpcService;
/**
* Rpc用戶服務
* Class RpcUserService
* @package App\Rpc
* name: 服務名稱全局唯一
* protocol: 服務協議:jsonrpc-http, jsonrpc, jsonrpc-tcp-length-check
* @RpcService(name="UserServiceServer", protocol="jsonrpc-http", server="jsonrpc-http", publishTo="consul")
*/
class UserServiceServer implements UserServiceInter
{
/**
* @Inject()
* @var ResJson
*/
public $resJson;
/**
* 獲取用戶信息
* @param int $userId
* @return string
*/
public function getUserInfo(int $userId) : string
{
$array['user_id'] = $userId;
$array['user_name'] = "PHP";
return $this->resJson->returnJsonString(ResJson::CODE_200, $array);
}
/**
* 獲取用戶列表
* @param int $page 頁碼數
* @param int $pageSize 每頁條數
* @param array $params 可選參數
* @return string
*/
public function getUserList(int $page, int $pageSize, array $params = []): string
{
$user[] = ['user_id' => 1, 'user_name' => 'Bill'];
$user[] = ['user_id' => 2, 'user_name' => 'Taylor'];
$user[] = ['user_id' => 3, 'user_name' => 'Jerry'];
return $this->resJson->returnJsonString(ResJson::CODE_200, $user);
}
}
定義服務消費者
<?php
declare(strict_types=1);
namespace App\Rpc\Client;
use App\Rpc\Inter\UserServiceInter;
use Hyperf\RpcClient\AbstractServiceClient;
class UserServiceClient extends AbstractServiceClient implements UserServiceInter
{
/**
* 服務提供者的服務名稱
* @var string
*/
protected $serviceName = "UserServiceServer";
/**
* 定義對應服務提供者的服務協議
* @var string
*/
protected $protocol = 'jsonrpc-http';
public function getUserInfo(int $userId) : string
{
return $this->__request(__FUNCTION__, compact('userId'));
}
public function getUserList(int $page, int $pageSize, array $params = []): string
{
return $this->__request(__FUNCTION__, compact('page', 'pageSize', 'params'));
}
}
使用Rpc服務
在config/autoload/dependencies.php 內定義 UserServiceInter 和 UserServiceClient 的關系
// 這樣便可以通過注入 UserServiceInter 接口來使用客戶端了
\App\Rpc\Inter\UserServiceInter::class => \App\Rpc\Client\UserServiceClient::class,
這樣便可以通過注入 UserServiceInter 接口來使用客戶端了。
Controller 代碼:
<?php
declare(strict_types=1);
namespace App\Admin\Controller;
use App\Admin\Model\UserModel;
use App\Admin\Service\UserService;
use App\Event\AppException;
use App\Rpc\Inter\UserServiceInter;
use Hyperf\DbConnection\Db;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\Utils\Context;
use Psr\EventDispatcher\EventDispatcherInterface;
use function _HumbugBoxa5be08ba8ddb\React\Promise\Stream\first;
/**
* 用戶控制器
* Class UserController
* @package App\Admin\Controller
* @AutoController()
*/
class UserController extends AdminBaseController
{
/**
* @Inject()
* @var UserServiceInter
*/
public $rpcUserService;
public function rpc()
{
$arr = $this->rpcUserService->getUserInfo(919);
var_dump($arr);
return $arr;
}
public function rpcuserlist()
{
$arr = $this->rpcUserService->getUserList(1, 10);
var_dump($arr);
return $arr;
}
}