类对象支持库(旁路插件)。路径:支持库 → 扩展类库。
| 类 | 插件 | 用途 |
|---|---|---|
| gRPC类 | supportlib.grpc |
一元调用:同步/异步、重试、截止时间、取消、可选 gzip |
| gRPC流类 | supportlib.grpc.stream |
流式:服务端流 / 客户端流 / 双向流 |
免费,随整包 IDE。工程里用到哪个类,就只链接对应模块。消息载荷用 Protobuf类 编解码(或 proto_gen_ypl 生成字段名辅助)。
类型名必须写完整「gRPC类」「gRPC流类」。声明时自动创建。
硬约束
- 方法路径形如
/包名.服务名/方法名(与.proto的package/service/rpc对应)。 - 传输为 HTTPS + HTTP/2(通常需要 Windows 10 及以上)。
- 请求/响应是 protobuf 线格式字节集,不是 JSON 文本。
- 本库是 客户端;不能在本机起 gRPC 服务端。
- 回调在工作线程触发:
置完成回调/置消息回调不要直接改窗体控件,请投递到定时器或界面线程。 - 回调签名不必改;自定义上下文挂在对象上(可选,一个文本槽):
- 不需要参数:
置完成回调(&完成),回调仍写函数 完成()。 - 简单标签:置完成回调(&完成, "订单A"),回调里取回调参数()。 - 多字段 / 不同类型 / 数组(推荐):把 JSON类 编码后的文本放进回调参数,回调里再解码(见下方「回调参数用 JSON」)。 - 流式同理:置/取消息回调参数、置/取完成回调参数。 - 客户端流在 Windows 上会先缓冲写出的消息,在
结束客户端流/写完成时一次发出(避免 HTTP/2 未知长度请求体被提前结束)。超大无限上传请自行分段多次打开。
适用场景(实战)
| 场景 | 建议 |
|---|---|
| 登录、查单、配置拉取、设备注册 | gRPC类 一元 |
| 管理端调公司内部微服务 / gRPC 网关 | gRPC类 + 置元数据 鉴权 |
| 任务进度、日志尾随、状态订阅 | gRPC流类 打开服务端流 |
| 埋点/采样批量上报、分片上传 | gRPC流类 打开客户端流 |
| 对话、远程指令来回 | gRPC流类 打开双向流 |
| 界面不能卡 | 异步(真) + 定时器轮询 已完成,或 置完成回调 |
| 对方偶发不可用 | 置重试;慢接口用 置截止时间 / 取消 |
与 HTTP类 对比:已有 .proto、要强类型与流式时用 gRPC;公开 REST / 浏览器直连仍用 HTTP。
工程接入
- 插件目录(随整包 IDE,免费,不必单独上传官网):
-
plugins/supportlib.grpc/→ gRPC类 -plugins/supportlib.grpc.stream/→ gRPC流类 - 消息编解码另需plugins/supportlib.protobuf/(Protobuf类) - 回调里传多字段/数组时另需 JSON类 - 在源码中声明对象即可自动引用,例如:
gRPC类 c
gRPC流类 s
Protobuf类 请求
- 打开工程后请 重新生成 再运行,确保链接到当前插件库(换过 IDE/插件版本后尤其重要)。
- 类型名必须写完整中文:「gRPC类」「gRPC流类」「Protobuf类」,不要写成
GrpcClient/Protobuf。 - 传输依赖系统 HTTPS + HTTP/2;通常需要 Windows 10 及以上。开发自签证书可
置校验证书(假),正式环境请校验并使用真实地址。
本库是 客户端。本机没有 gRPC 服务时,可用示例工程自带的 Python 模拟器联调(见下文「示例工程」)。
示例工程(对照练习)
随产品示例提供本机 HTTPS+HTTP/2 联调工程(目录名 grpc_smoke,含 _start_mock.bat 与说明 README.md)。打开后按步骤操作;按钮与 API 对照如下。
| 步骤 | 操作 |
|---|---|
| 1 | 安装 Python 3,命令行可执行 python |
| 2 | 双击 _start_mock.bat,看到 gRPC mock https://127.0.0.1:50051/ 后保持窗口开启 |
| 3 | 用 IDE 打开工程 → 重新生成 → 运行 |
| 4 | 按按钮分场景;日志末尾应出现 失败=0 |
| 按钮 | 演示内容 | 主要 API |
|---|---|---|
| Protobuf | 本地置/取/编码/解码(可不启模拟器) | Protobuf类 |
| 一元 | 同步 调用 + 置元数据 |
调用 置元数据 取状态码 |
| 异步 | 异步(真) + 定时器轮询 |
已完成 取响应 |
| 回调JSON | 置完成回调 + JSON 用户参数 |
置完成回调 取回调参数 + JSON类 |
| 进阶 | 不可用(14)、重试、截止、异步取消 | 置重试 置截止时间 取消 |
| 流式 | Watch 服务端流 3 条、Upload 客户端流 n=2 |
打开服务端流 读消息 打开客户端流 结束客户端流 |
| 双向流 | Chat 写 ping / 读 echo / 写完成 |
打开双向流 写消息 写完成 |
模拟器方法路径:/demo.Greeter/SayHello、Unavailable、Flaky、Slow、Watch、Upload、Chat。请求/响应为 Protobuf 线格式;示例用字段号 1 表示字符串。
快速开始 · 一元同步
Protobuf类 请求
请求.置文本(1, "world")
gRPC类 c
c.置地址("https://127.0.0.1:50051")
c.置超时(10000)
c.置截止时间(8000)
c.置重试(2, 200)
c.置校验证书(假) ' 仅开发/自签证书
字节集 响应 = c.调用("/demo.Greeter/SayHello", 请求.编码())
如果 (c.取状态码() <> 0) {
输出(c.取错误())
返回 ()
}
Protobuf类 答复
答复.解码(响应)
输出(答复.取文本(1))
快速开始 · 一元异步
gRPC类 c
' 回调签名始终无参;需要上下文时用取回调参数()
函数 调用完成()
输出(c.取回调参数()) ' → 订单查询(若曾置入)
如果 (c.取状态码() <> 0) {
输出(c.取错误())
返回 ()
}
字节集 r = c.取响应()
Protobuf类 请求
请求.置文本(1, "async")
c.置地址("https://127.0.0.1:50051")
c.置校验证书(假)
c.异步(真)
' 写法一:登记回调时顺带传参
c.置完成回调(&调用完成, "订单查询")
' 写法二:先赋值再登记(第二参可省略)
' c.置回调参数("订单查询")
' c.置完成回调(&调用完成)
c.调用("/demo.Greeter/SayHello", 请求.编码())
' 不需要自定义参数:c.置完成回调(&调用完成) 即可
回调参数用 JSON(多类型 / 数组)
对象上只有一个文本槽;要传整数、逻辑、数组等,请用 JSON 文本(依赖 JSON类):
gRPC类 c
JSON类 j
函数 调用完成()
JSON类 回
如果 (回.解析(c.取回调参数()) == 假) {
输出(回.取错误())
返回 ()
}
整数 订单号 = 回.取整数("id")
文本 备注 = 回.取文本("note")
逻辑 加急 = 回.取逻辑("rush")
整数 n = 回.取成员数("tags") ' 数组长度
文本 首标签 = 回.取文本("tags[0]")
输出(到文本(订单号) + " " + 备注 + " " + 首标签)
j.置整数("id", 1001)
j.置文本("note", "加急单")
j.置逻辑("rush", 真)
j.置文本("tags[0]", "vip")
j.置文本("tags[1]", "mail")
c.异步(真)
c.置完成回调(&调用完成, j.到文本()) ' 等价:c.置回调参数(j.到文本())
c.调用("/demo.Greeter/SayHello", 请求.编码())
只要标签、不要结构时,直接传普通文本即可,不必包 JSON。路径如 tags[0] 见 JSON类。
快速开始 · 服务端流
gRPC流类 s
s.置地址("https://127.0.0.1:50051")
s.置校验证书(假)
Protobuf类 请求
请求.置文本(1, "watch")
如果 (s.打开服务端流("/demo.Greeter/Watch", 请求.编码()) == 假) {
输出(s.取错误())
返回 ()
}
当 (真) {
字节集 m = s.读消息()
如果 (字节集长度(m) == 0) {
跳出 ()
}
Protobuf类 片
片.解码(m)
输出(片.取文本(1))
}
s.关闭()
注意:读循环请用 当 (真),不要写 循环 (真, n)(后者会变成只计次 1 次)。
快速开始 · 客户端流
gRPC流类 s
s.置地址("https://127.0.0.1:50051")
s.置校验证书(假)
如果 (s.打开客户端流("/demo.Greeter/Upload") == 假) {
输出(s.取错误())
返回 ()
}
Protobuf类 a
a.置文本(1, "a")
Protobuf类 b
b.置文本(1, "b")
s.写消息(a.编码())
s.写消息(b.编码())
字节集 汇总 = s.结束客户端流()
Protobuf类 回
回.解码(汇总)
输出(回.取文本(1))
s.关闭()
快速开始 · 双向流
gRPC流类 s
s.置地址("https://127.0.0.1:50051")
s.置校验证书(假)
如果 (s.打开双向流("/demo.Greeter/Chat") == 假) {
输出(s.取错误())
返回 ()
}
Protobuf类 片
片.置文本(1, "ping")
s.写消息(片.编码())
字节集 回 = s.读消息() ' HTTP/2 下可与写交错
s.写完成()
s.关闭()
.proto → 字段名辅助
python build\proto_gen_ypl.py path\to\hello.proto -o 工程目录
生成如 HelloRequest_pb.yc,内含 置_HelloRequest_name(Protobuf类 消息, …) / 取_…。扩展类形参按值传句柄,不要写 &。
字段号与 .proto 一致;示例工程为简单演示直接用数字字段号,正式业务建议用生成辅助或统一常量。
状态码与错误
取状态码():0= 成功;非 0 为 gRPC 状态(如1已取消、4超过截止时间、14服务不可用)。取错误():中文说明,形如gRPC类:服务不可用(状态码 14):…(面向用户,不含底层系统错误码)。取状态消息():服务端grpc-message(若有)。
常见状态(便于对照日志):
| 码 | 含义(概要) | 典型触发 |
|---|---|---|
| 0 | 成功 | 正常返回 |
| 1 | 已取消 | 取消() |
| 4 | 超过截止时间 | 置截止时间 到期、或超时 |
| 14 | 服务不可用 | 对方返回 unavailable;可用 置重试 |
每次调用后务必看 取状态码();不要只看返回的字节集是否为空。
易错与排查
| 现象 | 原因与处理 |
|---|---|
| 服务端流只收到 1 条 | 读循环写成了 循环 (真, n)(会变成计次 1)。请用 当 (真) { … 跳出 } |
| 回调里改按钮/文本框异常 | 完成/消息回调在工作线程。只改模块变量,界面更新放到定时器或界面线程 |
异步 调用 立刻得到空字节集 |
正常。应用 已完成 / 置完成回调 后再 取响应 |
| 想传整数/数组给回调却无效 | 回调签名固定无用户形参;上下文只有一个文本槽。多类型请放 JSON 文本,见上文 |
| 客户端流对端收不到中间包 | Windows 上写出先缓冲,在 结束客户端流 / 写完成 时一次发出 |
| 自签证书连不上 | 开发可 置校验证书(假);确认地址为 https://… 且模拟器在跑 |
| 大量 FAIL / 截止异常 | 换过插件后未 重新生成;或 50051 上仍是旧模拟器进程 |
| Flaky 重试不稳定 | 模拟器进程内计数;反复点「进阶」前可重启 _start_mock.bat |
| 与 HTTP类 混用 JSON 当 gRPC 正文 | gRPC 载荷是 protobuf 字节集,不是 JSON 文本 |
实战写法摘要
鉴权元数据(每次调用前):
c.清空元数据()
c.置元数据("authorization", "Bearer " + token)
字节集 r = c.调用("/pkg.Svc/Method", 请求.编码())
界面不卡:异步 + 定时器(示例「异步」按钮):
c.异步(真)
c.调用(路径, 请求.编码())
定时器.启动(50, &轮询) ' 轮询里判断 已完成() 再取响应
界面不卡:异步 + 完成回调(示例「回调JSON」按钮):
c.异步(真)
c.置完成回调(&完成, j.到文本())
c.调用(路径, 请求.编码())
' 函数 完成() 内:取状态码 / 取响应 / 取回调参数;勿直接改控件
订阅进度(服务端流): 打开 → 当 (真) 读到空跳出 → 关闭。
批量上报(客户端流): 打开 → 多次 写消息 → 结束客户端流 取汇总 → 关闭。
对话(双向流): 打开 → 写/读可交错 → 写完成 → 关闭。
gRPC类/方法
置地址
- 签名:
无 置地址(文本 地址) - 说明:设置服务根地址。可写
https://主机:端口,或省略协议(默认按 https 处理)。后续调用都打到该主机。 - 参数一│文本 地址: 如
"https://127.0.0.1:50051"。 - 示例:
置地址("https://api.example.com:443")
置超时
- 签名:
无 置超时(整数 毫秒) - 说明:解析/连接/发送/接收共用超时。与
置截止时间同时设置时取更严(更短)的一方。 - 参数一│整数 毫秒: >0 生效;未设时默认约 30000。
- 示例:
置超时(10000)
置截止时间
- 签名:
无 置截止时间(整数 毫秒) - 说明:从调用开始起的总时限。超时后状态码多为
4(超过截止时间)。0= 不额外限制(仍受置超时约束)。HTTP/2 下除会话超时外还有看门狗,避免慢响应拖死界面。 - 参数一│整数 毫秒: 如
400表示约 0.4 秒内必须结束。 - 示例:
置截止时间(5000)
置校验证书
- 签名:
无 置校验证书(逻辑 校验) - 说明:HTTPS 是否校验证书。
假= 忽略自签/主机名不匹配等(仅建议开发或内网)。默认校验。 - 示例:
置校验证书(假)
置压缩
- 签名:
无 置压缩(逻辑 启用) - 说明:
真= 请求消息体用 gzip(对方需支持grpc-encoding: gzip)。默认关。 - 示例:
置压缩(真)
置重试
- 签名:
无 置重试(整数 次数, [整数 间隔毫秒=200]) - 说明:首次失败后的额外重试次数。仅对可重试状态生效(如超时、资源耗尽、中止、服务不可用)。
已取消与成功不会重试。间隔会随次数递增。 - 参数一│整数 次数:
0= 不重试;3= 最多共 4 次尝试。 - 参数二│整数 间隔毫秒: 基础退避间隔,默认 200。
- 示例:
置重试(3, 80)
清空元数据 / 置元数据
- 签名:
无 清空元数据()·无 置元数据(文本 键, 文本 值) - 说明:自定义请求元数据(HTTP/2 头),常用于鉴权。每次
调用前可清空再设置。 - 示例:
置元数据("authorization", "Bearer xxx")
异步 / 取异步
- 签名:
无 异步(逻辑 启用)·逻辑 取异步() - 说明:
异步(真)后,调用在后台执行并立刻返回空字节集;用已完成/置完成回调/ 定时器取结果。假= 恢复同步(调用阻塞到结束)。 - 示例:
异步(真)
已完成
- 签名:
逻辑 已完成() - 说明:异步模式下,后台调用是否已结束。同步模式或未在调用时为真。
- 示例:
如果 (c.已完成()) { … }
取消
- 签名:
逻辑 取消() - 说明:取消进行中的异步调用。成功发起取消后状态码多为
1(已取消)。无进行中任务时返回假。 - 示例:
c.取消()
置完成回调
- 签名:
无 置完成回调([子程序指针 回调=0], [文本 用户参数=""]) - 说明:异步结束时触发。回调固定
函数 名()(忘了写用户参数形参也没关系)。可选第二参:非空文本写入回调参数;省略则不改已有值。传0清除回调并清空参数。工作线程,勿直接改控件。 - 参数一│子程序指针:
&调用完成或0。 - 参数二│文本 用户参数: 可选,如
"订单查询"。 - 示例:
置完成回调(&调用完成)·置完成回调(&调用完成, "订单查询")
置回调参数 / 取回调参数
- 签名:
无 置回调参数(文本 用户参数)·文本 取回调参数() - 说明:赋值用
置回调参数(""清空);取值在回调里取回调参数()。与置完成回调第二参等效。
槽位是单个文本:多参数、不同类型、数组请放入 JSON 文本(见上文「回调参数用 JSON」),不要期望回调形参里直接出现整数/数组。
调用
- 签名:
字节集 调用(文本 方法路径, 字节集 请求) - 说明:发起一元 RPC。同步:返回响应消息字节集(失败可能为空,务必看
取状态码)。异步:立刻返回空,完成后用取响应。 - 参数一│文本 方法路径: 如
"/demo.Greeter/SayHello"。 - 参数二│字节集 请求: 一般为
Protobuf类.编码()结果;可空。 - 示例:
字节集 r = c.调用("/demo.Greeter/SayHello", 请求.编码())
取响应
- 签名:
字节集 取响应() - 说明:取出最近一次异步调用的响应消息(成功时)。建议在
已完成为真且状态码为 0 后调用。 - 示例:
字节集 r = c.取响应()
取状态码 / 取状态消息 / 取错误
- 签名:
整数 取状态码()·文本 取状态消息()·文本 取错误() - 说明:最近一次调用的结果。
0成功;取错误为面向用户的中文说明。
gRPC流类/方法
配置(与一元类似)
置地址 置超时 置截止时间 置校验证书 置压缩 清空元数据 置元数据 —— 语义同 gRPC类(流式无 置重试)。
置消息回调
- 签名:
无 置消息回调([子程序指针 回调=0], [文本 用户参数=""]) - 说明:每条消息回调;结束时再调且结束=真。签名固定
函数 名(字节集 消息, 逻辑 结束)。可选第二参写入消息回调参数。读线程,勿直接改 UI。 - 示例:
置消息回调(&收到一片)·置消息回调(&收到一片, "订阅A")
置完成回调
- 签名:
无 置完成回调([子程序指针 回调=0], [文本 用户参数=""]) - 说明:流结束时回调。签名固定
函数 名()。可选第二参。工作线程。 - 示例:
置完成回调(&流结束, "订阅A")
置/取消息回调参数 · 置/取完成回调参数
- 说明:与一元相同——各一个文本槽;复杂数据用 JSON 文本;
""清空。
取消
- 签名:
逻辑 取消() - 说明:取消当前流(关闭进行中的请求)。状态码多为已取消。
打开服务端流
- 签名:
逻辑 打开服务端流(文本 方法路径, 字节集 请求) - 说明:发送一条请求,然后连续接收多条响应。成功返回真,再用
读消息或消息回调取片。 - 示例:
打开服务端流("/demo.Greeter/Watch", 请求.编码())
读消息 / 还有消息
- 签名:
字节集 读消息()·逻辑 还有消息() - 说明:
读消息阻塞等待下一条;流结束或超时返回空字节集。还有消息表示队列里是否已有可读消息(不阻塞)。 - 示例:见上方「服务端流」快速开始。
打开客户端流 / 写消息 / 结束客户端流
- 签名:
逻辑 打开客户端流(文本 方法路径)·逻辑 写消息(字节集 消息)·字节集 结束客户端流() - 说明:打开后多次
写消息,最后结束客户端流发出全部缓冲并读取一条汇总响应。适合批量上报。 - 示例:见上方「客户端流」快速开始。
打开双向流 / 写完成
- 签名:
逻辑 打开双向流(文本 方法路径)·逻辑 写完成() - 说明:打开后可读可写交错(HTTP/2)。写端结束时调
写完成。仍可用读消息/写消息。 - 示例:见上方「双向流」快速开始。
关闭
- 签名:
无 关闭() - 说明:关闭当前流与网络句柄,可再次
打开*流。切换流类型前建议先关闭。
取状态码 / 取状态消息 / 取错误
- 说明:同 gRPC类,表示最近一次流操作的状态。