fguillot json rpc_使用PHP协程框架Hyperf搭建JSON RPC服务

本文介绍了如何利用PHP协程框架Hyperf构建基于TCP的JSON-RPC服务。从创建项目开始,选择JSON-RPC协议,到配置服务提供者和消费者,最后启动并演示服务。通过示例展示了如何实现远程过程调用,适用于高并发场景。
摘要由CSDN通过智能技术生成

JSON RPC:基于JSON格式的跨语言远程过程调用协议

Hyperf:基于Swoole的PHP协程框架,适合配合Docker搭建大型集群项目处理高并发场景

1、使用Hyperf搭建适配TCP协议的JSON RPC服务composer create-project hyperf/hyperf-skeleton Server/Client

What time zone do you want to setup ?

[n] Default time zone for php.ini

Make your selection or type a time zone name, like Asia/Shanghai (n): n

Which RPC protocol do you want to use ?

[1] JSON-RPC with Service Governance

[2] JSON-RPC

[3] gRPC

[n] None of the above

Make your selection or type a composer package name and version (n): 2

Which config center do you want to use ?

[1] Apollo

[2] Aliyun ACM

[n] None of the above

Make your selection or type a composer package name and version (n): 1

Do you want to use hyperf/constants component ?

[1] yes

[n] None of the above

Make your selection (n): 1

Do you want to use hyperf/async-queue component ? (A simple redis queue component)

[1] yes

[n] None of the above

Make your selection or type a composer package name and version (n): 1

Do you want to use hyperf/amqp component ?

[1] yes

[n] None of the above

Make your selection or type a composer package name and version (n): 1

Do you want to use hyperf/model-cache component ?

[1] yes

[n] None of the above

Make your selection or type a composer package name and version (n): 1

Do you want to use hyperf/elasticsearch component ?

[1] yes

[n] None of the above

Make your selection or type a composer package name and version (n): n

Do you want to use hyperf/tracer component ? (A open tracing protocol component, adapte with Zipkin etc.)

[1] yes

[n] None of the above

Make your selection or type a composer package name and version (n): 1

2、服务提供者(Server)的开发与配置

app目录结构:.

├── Constants

├── Controller

├── Exception

├── JsonRpc

│   ├── UserService.php

│   └── UserServiceInterface.php

├── Listener

├── Model

└── Process

server/app/JsonRpc/UserServiceInterface.php<?php

declare(strict_types=1);

namespace App\JsonRpc;

interface UserServiceInterface

{

/**

* 通过Id获取Token

* @param int $id ID

* @return string

*/

public function getTokenById(int $id): string;

}

server/app/JsonRpc/UserService.php<?php

declare(strict_types=1);

namespace App\JsonRpc;

use Hyperf\RpcServer\Annotation\RpcService;

/**

* Class UserService

* @RpcService(name="UserService", protocol="jsonrpc", server="jsonrpc")

*/

class UserService implements UserServiceInterface

{

public function getTokenById(int $id): string

{

return md5($id);

}

}

server/config/autoload/server.php<?php

declare(strict_types=1);

use Hyperf\Server\Server;

use Hyperf\Server\SwooleEvent;

return [

'mode' => SWOOLE_PROCESS,

'servers' => [

[

'name' => 'http',

'type' => Server::SERVER_HTTP,

'host' => '0.0.0.0',

'port' => 9501,

'sock_type' => SWOOLE_SOCK_TCP,

'callbacks' => [

SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'],

],

],

[

'name' => 'jsonrpc',

'type' => Server::SERVER_BASE,

'host' => '0.0.0.0',

'port' => 9505,

'sock_type' => SWOOLE_SOCK_TCP,

'callbacks' => [

SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\TcpServer::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'],

],

];

3、服务消费者(Client)的开发与配置

app目录结构:.

├── Constants

├── Controller

│   └── IndexController.php

├── Exception

├── JsonRpc

│   └── UserServiceInterface.php

├── Listener

├── Model

└── Process

client/app/JsonRpc/UserServiceInterface.php<?php

declare(strict_types=1);

namespace App\JsonRpc;

interface UserServiceInterface

{

/**

* 通过Id获取Token

* @param int $id ID

* @return string

*/

public function getTokenById(int $id): string;

}

client/app/Controller/IndexController.php<?php

namespace App\Controller;

use Hyperf\Di\Annotation\Inject;

use Hyperf\HttpServer\Annotation\AutoController;

use Hyperf\Utils\ApplicationContext;

use App\JsonRpc\CalculatorServiceInterface;

/**

* @AutoController()

*/

class IndexController extends AbstractController

{

public function index()

{

$user = $this->request->input('user', 'Hyperf');

$method = $this->request->getMethod();

return [

'method' => $method,

'message' => "Hello {$user}.",

];

}

public function get_token()

{

$server = ApplicationContext::getContainer()->get(UserServiceInterface::class);

var_dump($server->getTokenById(12345));

}

clientconfigautoloadserver.php<?php

declare(strict_types=1);

use Hyperf\Server\Server;

use Hyperf\Server\SwooleEvent;

return [

'mode' => SWOOLE_PROCESS,

'servers' => [

[

'name' => 'http',

'type' => Server::SERVER_HTTP,

'host' => '0.0.0.0',

'port' => 9510,

'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'],

],

];

clientconfigautoloadservices.php<?php

declare(strict_types=1);

return [

'consumers' => value(function(){

$consumers = [];

$services = [

'UserService' => App\JsonRpc\UserServiceInterface::class

];

foreach ($services as $name => $interface) {

$consumers[] = [

'name' => $name,

'service' => $interface,

'protocol' => 'jsonrpc',

'load_balancer' => 'random',

'nodes' => [

['host' => '127.0.0.1', 'port' => 9505]

],

'options' => [

'pool' => [

'min_connections' => 1,

'max_connections' => 32,

'connect_timeout' => 10.0,

'wait_timeout' => 3.0,

'heartbeat' => -1,

'max_idle_time' => 60.0,

]

]

];

}

return $consumers;

}),

];

4、服务启动与演示

启动:[Dark-Enchanter:/usr/local/var/www/jsonrpc/server » php ./bin/hyperf.php start

[Dark-Enchanter:/usr/local/var/www/jsonrpc/client » php ./bin/hyperf.php start

演示:[Dark-Enchanter:/usr/local/var/www/jsonrpc » curl http://127.0.0.1:9510/get_token

827ccb0eea8a706c4c34a16891f84e7b

典型RPC架构图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值