# JSON RPC 服务 JSON RPC 是一种基于 JSON 格式的轻量级的 RPC 协议标准,易于使用和阅读。在 Hyperf 里由 [hyperf/json-rpc](https://github.com/hyperf-cloud/json-rpc) 组件来实现,可自定义基于 HTTP 协议来传输,或直接基于 TCP 协议来传输。 # 安装 ```bash composer require hyperf/json-rpc ``` # 使用 服务有两种角色,一种是 `服务提供者(ServiceProvider)`,即为其它服务提供服务的服务,另一种是 `服务消费者(ServiceConsumer)`,即依赖其它服务的服务,一个服务既可能是 `服务提供者(ServiceProvider)`,同时又是 `服务消费者(ServiceConsumer)`。而两者直接可以通过 `服务契约` 来定义和约束接口的调用,在 Hyperf 里,可直接理解为就是一个 `接口类(Interface)`,通常来说这个接口类会同时出现在提供者和消费者下。 ## 定义服务提供者 目前仅支持通过注解的形式来定义 `服务提供者(ServiceProvider)`,后续迭代会增加配置的形式。 我们可以直接通过 `@RpcService` 注解对一个类进行定义即可发布这个服务了: ```php 使用 `@RpcService` 注解需 `use Hyperf\RpcServer\Annotation\RpcService;` 命名空间。 ### 定义 JSON RPC Server HTTP Server (适配 `jsonrpc-http` 协议) ```php [ [ 'name' => 'jsonrpc-http', 'type' => Server::SERVER_HTTP, 'host' => '0.0.0.0', 'port' => 9504, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ SwooleEvent::ON_REQUEST => [\Hyperf\JsonRpc\HttpServer::class, 'onRequest'], ], ], ], ]; ``` TCP Server (适配 `jsonrpc` 协议) ```php [ [ 'name' => 'jsonrpc', 'type' => Server::SERVER_TCP, 'host' => '0.0.0.0', 'port' => 9503, 'sock_type' => SWOOLE_SOCK_TCP, 'callbacks' => [ SwooleEvent::ON_RECEIVE => [\Hyperf\JsonRpc\TcpServer::class, 'onReceive'], ], 'settings' => [ 'open_eof_split' => true, 'package_eof' => "\r\n", ], ], ], ]; ``` ## 发布到服务中心 目前仅支持发布服务到 `consul`,后续会增加其它服务中心。 发布服务到 `consul` 在 Hyperf 也是非常容易的一件事情,通过 `composer require hyperf/consul` 加载 Consul 组件(如果已安装则可忽略该步骤),然后再在 `config/autoload/consul.php` 配置文件内配置您的 `Consul` 配置即可,示例如下: ```php 'http://127.0.0.1:8500', ]; ``` 配置完成后,在启动服务时,Hyperf 会自动地将 `@RpcService` 定义了 `publishTo` 属性为 `consul` 的服务注册到服务中心去。 > 目前仅支持 `jsonrpc-http` 协议发布到服务中心去,其它协议的健康检查尚未实现 ## 定义服务消费者 一个 `服务消费者(ServiceConsumer)` 可以理解为就是一个客户端类,但在 Hyperf 里您无需处理连接和请求相关的事情,只需要定义一个类及相关属性即可。(v1.1会提供动态代理实现的客户端,使之更加简单便捷) ```php __request(__FUNCTION__, compact('a', 'b')); } } ``` 然后还需要在配置文件定义一个配置标记要从何服务中心获取节点信息,位于 `config/autoload/services.php` (如不存在可自行创建) ```php [ [ // 对应消费者类的 $serviceName 'name' => 'CalculatorService', // 这个消费者要从哪个服务中心获取节点信息,如不配置则不会从服务中心获取节点信息 'registry' => [ 'protocol' => 'consul', 'address' => 'http://127.0.0.1:8500', ], // 如果没有指定上面的 registry 配置,即为直接对指定的节点进行消费,通过下面的 nodes 参数来配置服务提供者的节点信息 'nodes' => [ ['host' => '127.0.0.1', 'port' => 9504], ], ] ], ]; ``` 这样我们便可以通过 `CalculatorService` 类来实现对服务的消费了,为了让这里的关系逻辑更加的合理,还应该在 `config/autoload/dependencies.php` 内定义 `CalculatorServiceInterface` 和 `CalculatorService` 的关系,示例如下: ```php return [ App\JsonRpc\CalculatorServiceInterface::class => App\JsonRpc\CalculatorService::class, ]; ``` 这样便可以通过注入 `CalculatorServiceInterface` 接口来使用客户端了。