fguillot json rpc_使用Hyperf框架搭建jsonrpc服务
一、開發項目劃分與搭建JSON RPC 是一種基于 JSON 格式的輕量級的 RPC 協議標準,易于使用和閱讀。在 Hyperf 里由 hyperf/json-rpc 組件來實現,可自定義基于 HTTP 協議來傳輸,或直接基于 TCP 協議來傳輸。
本次我選擇使用基于 TCP 協議的 jsonrpc 協議來搭建服務。
服務有兩種角色,一種是 服務提供者(ServiceProvider),即為其它服務提供服務的服務,另一種是 服務消費者(ServiceConsumer),即依賴其它服務的服務,一個服務既可能是 服務提供者(ServiceProvider),同時又是 服務消費者(ServiceConsumer)。而兩者直接可以通過 服務契約 來定義和約束接口的調用,在 Hyperf 里,可直接理解為就是一個 接口類(Interface),通常來說這個接口類會同時出現在提供者和消費者下。
本次我搭建了一個服務提供者 calculate,為其他服務提供計算功能;一個消費者,通過 jsonrpc 協議調用 calculate 提供的計算功能。搭建過程如下:
1、搭建 calculate 服務提供者
composer create-project hyperf/hyperf-skeleton calculate
WhichRPC protocoldoyou want touse?
[1]JSON-RPCwithServiceGovernance
[2]JSON-RPC
[3]gRPC
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):2
Whichconfig centerdoyou want touse?
[1]Apollo
[2]AliyunACM
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/constants component?
[1]yes
[n]Noneof the above
Makeyour selection(n):1
Doyou want tousehyperf/async-queue component?(A simple redis queue component)
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/amqp component?
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/model-cache component?
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/elasticsearch component?
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):n
Doyou want tousehyperf/tracer component?(A open tracing protocol component,adaptewithZipkinetc.)
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
2、搭建 gateway 服務消費者
composer create-project hyperf/hyperf-skeleton gateway
WhichRPC protocoldoyou want touse?
[1]JSON-RPCwithServiceGovernance
[2]JSON-RPC
[3]gRPC
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):2
Whichconfig centerdoyou want touse?
[1]Apollo
[2]AliyunACM
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/constants component?
[1]yes
[n]Noneof the above
Makeyour selection(n):1
Doyou want tousehyperf/async-queue component?(A simple redis queue component)
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/amqp component?
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/model-cache component?
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
Doyou want tousehyperf/elasticsearch component?
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):n
Doyou want tousehyperf/tracer component?(A open tracing protocol component,adaptewithZipkinetc.)
[1]yes
[n]Noneof the above
Makeyour selectionortype a composerpackagenameandversion(n):1
二、JSON RPC服務開發與配置
1、calculate 功能開發
app 目錄結構
app
Constants
Controller
Exception
JsonRpc
CalculatorService.php
CalculatorServiceInterface.php
Listener
Model
Process
app\JsonRpc\CalculatorService.php
namespaceApp\JsonRpc;
useHyperf\RpcServer\Annotation\RpcService;
/**
* Class CalculatorService
* @RpcService(name="CalculatorService", protocol="jsonrpc", server="jsonrpc")
*/
classCalculatorServiceimplementsCalculatorServiceInterface
{
publicfunctionadd(int$v1,int$v2):int
{
return$v1+$v2;
}
}
app\JsonRpc\CalculatorServiceInterface.php
declare(strict_types=1);
namespaceApp\JsonRpc;
interfaceCalculatorServiceInterface
{
publicfunctionadd(int$v1,int$v2):int;
}
calculate 服務配置
config\autoload\server.php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
useHyperf\Server\Server;
useHyperf\Server\SwooleEvent;
return[
'mode'=>SWOOLE_PROCESS,
'servers'=>[
[
'name'=>'jsonrpc',
'type'=>Server::SERVER_BASE,
'host'=>'0.0.0.0',
'port'=>9501,
'sock_type'=>SWOOLE_SOCK_TCP,
'callbacks'=>[
SwooleEvent::ON_RECEIVE=>[Hyperf\JsonRpc\TcpServer::class,'onReceive'],
],
'settings'=>[
'open_eof_split'=>true,
'package_eof'=>"\r\n",
]
],
],
'settings'=>[
'enable_coroutine'=>true,
'worker_num'=>swoole_cpu_num(),
'pid_file'=>BASE_PATH.'/runtime/hyperf.pid',
'open_tcp_nodelay'=>true,
'max_coroutine'=>100000,
'open_http2_protocol'=>true,
'max_request'=>100000,
'socket_buffer_size'=>2*1024*1024,
],
'callbacks'=>[
SwooleEvent::ON_BEFORE_START=>[Hyperf\Framework\Bootstrap\ServerStartCallback::class,'beforeStart'],
SwooleEvent::ON_WORKER_START=>[Hyperf\Framework\Bootstrap\WorkerStartCallback::class,'onWorkerStart'],
SwooleEvent::ON_PIPE_MESSAGE=>[Hyperf\Framework\Bootstrap\PipeMessageCallback::class,'onPipeMessage'],
],
];
2、gateway 消費者功能開發
app 目錄結構
app
Constants
Controller
IndexController.php
Exception
JsonRpc
CalculatorServiceInterface.php
Listener
Model
Process
app\JsonRpc\CalculatorServiceInterface.php
declare(strict_types=1);
namespaceApp\JsonRpc;
interfaceCalculatorServiceInterface
{
publicfunctionadd(int$v1,int$v2):int;
}
config\routes.php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
useHyperf\HttpServer\Router\Router;
Router::addRoute(['GET','POST','HEAD'],'/','App\Controller\IndexController@index');
Router::get('/add','App\Controller\IndexController@add');
app\Controller\IndexController.php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
namespaceApp\Controller;
useHyperf\Utils\Context;
useHyperf\Utils\Coroutine;
useHyperf\Utils\Parallel;
useHyperf\Utils\ApplicationContext;
useApp\JsonRpc\CalculatorServiceInterface;
useApp\JsonRpc\MathValue;
classIndexControllerextendsAbstractController
{
publicfunctionindex()
{
$user=$this->request->input('user','Hyperf');
$method=$this->request->getMethod();
return[
'method'=>$method,
'message'=>"Hello {$user}.",
];
}
publicfunctionadd()
{
$client=ApplicationContext::getContainer()->get(CalculatorServiceInterface::class);
$value=$client->add(10,20);
return$value;
}
}
gateway 服務配置
config\autoload\server.php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
useHyperf\Server\Server;
useHyperf\Server\SwooleEvent;
return[
'mode'=>SWOOLE_PROCESS,
'servers'=>[
[
'name'=>'http',
'type'=>Server::SERVER_HTTP,
'host'=>'0.0.0.0',
'port'=>9500,
'sock_type'=>SWOOLE_SOCK_TCP,
'callbacks'=>[
SwooleEvent::ON_REQUEST=>[Hyperf\HttpServer\Server::class,'onRequest'],
],
],
],
'settings'=>[
'enable_coroutine'=>true,
'worker_num'=>swoole_cpu_num(),
'pid_file'=>BASE_PATH.'/runtime/hyperf.pid',
'open_tcp_nodelay'=>true,
'max_coroutine'=>100000,
'open_http2_protocol'=>true,
'max_request'=>100000,
'socket_buffer_size'=>2*1024*1024,
],
'callbacks'=>[
SwooleEvent::ON_BEFORE_START=>[Hyperf\Framework\Bootstrap\ServerStartCallback::class,'beforeStart'],
SwooleEvent::ON_WORKER_START=>[Hyperf\Framework\Bootstrap\WorkerStartCallback::class,'onWorkerStart'],
SwooleEvent::ON_PIPE_MESSAGE=>[Hyperf\Framework\Bootstrap\PipeMessageCallback::class,'onPipeMessage'],
],
];
config\autoload\services.php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://doc.hyperf.io
* @contact group@hyperf.io
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
*/
return[
'consumers'=>[
[
// name 需與服務提供者的 name 屬性相同
'name'=>'CalculatorService',
// 服務接口名,可選,默認值等于 name 配置的值,如果 name 直接定義為接口類則可忽略此行配置,如 name 為字符串則需要配置 service 對應到接口類
'service'=>\App\JsonRpc\CalculatorServiceInterface::class,
// 對應容器對象 ID,可選,默認值等于 service 配置的值,用來定義依賴注入的 key
'id'=>\App\JsonRpc\CalculatorServiceInterface::class,
// 服務提供者的服務協議,可選,默認值為 jsonrpc-http
'protocol'=>'jsonrpc',
// 負載均衡算法,可選,默認值為 random
'load_balancer'=>'random',
// 這個消費者要從哪個服務中心獲取節點信息,如不配置則不會從服務中心獲取節點信息
// 'registry' => [
// 'protocol' => 'consul',
// 'address' => 'http://127.0.0.1:8500',
// ],
// 如果沒有指定上面的 registry 配置,即為直接對指定的節點進行消費,通過下面的 nodes 參數來配置服務提供者的節點信息
'nodes'=>[
['host'=>'127.0.0.1','port'=>9501],
],
]
],
];
三、服務啟動與通信演示
1、啟動 calculate 服務root@cosyphp-VirtualBox:~#cd/home/wwwroot/calculate/
root@cosyphp-VirtualBox:/home/wwwroot/calculate# php bin/hyperf.php start
2、啟動 gateway 服務root@cosyphp-VirtualBox:~#cd/home/wwwroot/gateway/
root@cosyphp-VirtualBox:/home/wwwroot/gateway# php bin/hyperf.php start
3、請求 gateway 服務root@cosyphp-VirtualBox:~#curl http://127.0.0.1:9500/add
30
root@cosyphp-VirtualBox:~#
四、各服務關系總覽
總結
以上是生活随笔為你收集整理的fguillot json rpc_使用Hyperf框架搭建jsonrpc服务的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 社区团购怎么做 按照下面几个步骤做
- 下一篇: xa 全局锁_fescar锁设计和隔离级