# GRPC 插件 ## 相关链接 参考示例: - {{ '[grpc_plugin]({}/src/examples/plugins/grpc_plugin)'.format(code_site_root_path_url) }} ## 插件概述 **grpc_plugin** 是一个基于 [gRPC 协议](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) 实现的 rpc 后端插件,此插件为 AimRT 提供了以下组件: - `grpc`类型 RPC 后端 插件的配置项如下: | 节点 | 类型 | 是否可选| 默认值 | 作用 | | ---- | ---- | ---- | ---- | ---- | | thread_num | unsigned int | 可选 | 2 | grpc 插件使用的线程数 | | listen_ip | string | 可选 | "0.0.0.0" | grpc 监听 IP | | listen_port | unsigned int | 必选 | - | grpc 监听端口,端口不能被占用 | 以下是一个简单的示例: ```yaml aimrt: plugin: plugins: - name: grpc_plugin path: ./libaimrt_grpc_plugin.so options: thread_num: 4 listen_ip: 127.0.0.1 listen_port: 50082 ``` 关于 **grpc_plugin** 的配置,使用注意点如下: - `thread_num` 表示 grpc 插件使用的线程数。 - `listen_ip` 用于配置 grpc 服务监听的地址,默认是"0.0.0.0",如果仅想在指定网卡上监听,可以将其改为指定 IP。 - `listen_port` 用于配置 grpc 服务监听的端口,此项为必填项,使用者必须确保端口未被占用,否则插件会初始化失败。 此外,在使用 **grpc_plugin** 时,RPC Server 处理方法、RPC Client 返回时,使用的都是 **grpc_plugin** 提供的自有线程执行器,当使用者在回调中阻塞了线程时,有可能导致 **grpc_plugin** 线程池耗尽,从而无法继续接收/发送消息。正如 Module 接口文档中所述,一般来说,如果回调中的任务非常轻量,那就可以直接在回调里处理;但如果回调中的任务比较重,那最好调度到其他专门执行任务的执行器里处理。 ## grpc 类型 RPC 后端 `grpc` 类型的 RPC 后端是 **grpc_plugin** 中提供的 RPC 后端,用于通过 gRPC 的方式来调用和处理 RPC 请求。 注意事项: * 当前 gRPC 插件仅支持 HTTP2 明文协议,不支持 TLS 加密协议。 * 当前 gRPC 插件仅支持一元 RPC 调用,不支持流式 RPC 调用。 * 当前 gRPC 插件不支持 HTTP2 消息压缩。 **grpc_plugin** 所有的配置项如下: | 节点 | 类型 | 是否可选| 默认值 | 作用 | | ---- | ---- | ---- | ---- | ---- | | clients_options | array | 可选 | [] | 客户端发起 RPC 请求时的规则 | | clients_options[i].func_name | string | 必选 | "" | RPC Func 名称,支持正则表达式 | | clients_options[i].server_url | string | 必选 | "" | RPC Func 发起调用时请求的 url | 以下是一个简单的客户端的示例: ```yaml aimrt: plugin: plugins: - name: grpc_plugin path: ./libaimrt_grpc_plugin.so options: thread_num: 4 listen_ip: 127.0.0.1 listen_port: 50081 rpc: backends: - type: grpc options: clients_options: - func_name: "(.*)" server_url: "http://127.0.0.1:50080" clients_options: - func_name: "(.*)" enable_backends: [grpc] ``` 以下则是一个简单的服务端的示例: ```yaml aimrt: plugin: plugins: - name: grpc_plugin path: ./libaimrt_grpc_plugin.so options: thread_num: 4 listen_ip: 127.0.0.1 listen_port: 50080 rpc: backends: - type: grpc servers_options: - func_name: "(.*)" enable_backends: [grpc] ``` 以上示例中,Server 端监听了本地的 50080 端口,Client 端则配置了所有的 RPC 请求都通过 grpc 后端请求到`http://127.0.0.1:50080`这个地址,也就是服务端监听的地址,从而完成 RPC 的调用闭环。 [gRPC 协议](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md) 使用 HTTP2 作为传输协议,常规的 curl 工具较难构造,可以使用 [grpcurl 工具](https://github.com/fullstorydev/grpcurl) 来对 gRPC 服务进行调试,例如通过以下命令,即可发送一个消息到指定模块上去触发对应的回调: ```shell grpcurl -plaintext \ -import-path /path/to/aimrt/src/protocols/example \ -proto rpc.proto \ -d '{"msg": "test msg"}' \ -max-time 1.0 \ localhost:50050 aimrt.protocols.example.ExampleService/GetFooData \ -vv ``` 以上命令中,`-plaintext` 表示使用 h2c 协议(即 HTTP2 明文协议,不进行加密),`-import-path` 表示导入 gRPC 协议的目录,`-proto` 表示导入 gRPC 协议的文件,`-d` 表示发送的消息内容,`-max-time` 表示最大超时时间,`-vv` 表示输出详细信息。 开发者还可以参考{{ '[grpc_plugin]({}/src/examples/plugins/grpc_plugin)'.format(code_site_root_path_url) }}中的示例,与原生 grpc 服务进行通信。