133 lines
4.0 KiB
Markdown
133 lines
4.0 KiB
Markdown
|
|
# gRPC 控制流协议摘要(ControlService)
|
|||
|
|
|
|||
|
|
## 接口
|
|||
|
|
- 服务:`control.v1.Control`
|
|||
|
|
- RPC:`ControlStream(stream ClientMessage) returns (stream ServerMessage)`
|
|||
|
|
- 双向长连接,客户端与控制端可任意时序发消息。
|
|||
|
|
|
|||
|
|
## 消息结构(摘自 proto/control.proto)
|
|||
|
|
- `ClientMessage` oneof:
|
|||
|
|
- `Hello`:client_id、version、hostname、printers[]
|
|||
|
|
- `PrintResult`:request_id、ok、printer、message、retries_used
|
|||
|
|
- `Pong`:nonce(对应 Ping)
|
|||
|
|
- `PrinterUpdate`:printers[]
|
|||
|
|
- `ServerMessage` oneof:
|
|||
|
|
- `PrintInstruction`:request_id、pdf_data(bytes)、PrintParams
|
|||
|
|
- `Ping`:nonce
|
|||
|
|
- `PrintParams`:copies、duplex(one_sided/long_edge/short_edge)、color(auto/color/monochrome)、media、quality(draft/normal/high)、orientation(portrait/landscape)、job_name、printer(optional 指定目标打印机)
|
|||
|
|
- `PrinterInfo`:id、name、host、uri、state、accepting_jobs、color_supported、active_jobs、ppm、ppm_color、reasons[]
|
|||
|
|
|
|||
|
|
## 客户端行为(当前实现)
|
|||
|
|
- 建立流后立即发送 `Hello`,携带当前打印机快照。
|
|||
|
|
- 后台按配置刷新(默认 10s,最小 5s)检测变更,发送 `PrinterUpdate`。
|
|||
|
|
- 收到 `Ping{nonce}` 立即回 `Pong{nonce}`。
|
|||
|
|
- 收到 `PrintInstruction`:
|
|||
|
|
- 将 pdf_data 落盘临时文件。
|
|||
|
|
- 按调度策略(默认 least_queued,支持指定 printer;尊重彩色需求和可用性)分发到 CUPS。
|
|||
|
|
- 成功/失败后返回 `PrintResult{ok, printer, message, retries_used}`。
|
|||
|
|
- 连接出错自动指数退避重连(1s 起,最大 10s),控制端无需主动重连。
|
|||
|
|
|
|||
|
|
## 字段语义补充
|
|||
|
|
- `color_supported`:客户端基于 CUPS 选项判定,保守为 false 以避免误判。
|
|||
|
|
- `state`:CUPS 状态字符串(Idle/Processing/Stopped 等)。
|
|||
|
|
- `reasons`:CUPS 状态原因列表(offline/jam/paper-out 等)。
|
|||
|
|
- `ppm`/`ppm_color`:若 CUPS 未提供则为缺省/0。
|
|||
|
|
|
|||
|
|
## 控制端最小交互建议
|
|||
|
|
1) 等待首条 `Hello`,登记客户端与打印机列表。
|
|||
|
|
2) 定期/按需发送 `Ping` 保活。
|
|||
|
|
3) 下发打印用 `PrintInstruction`(带 request_id 以关联结果)。
|
|||
|
|
4) 接收 `PrintResult` 做业务回执;可订阅 `PrinterUpdate` 更新状态。
|
|||
|
|
|
|||
|
|
## 开发/测试命令
|
|||
|
|
- 生成/查看 proto:文件位于 `proto/control.proto`,由 `tonic-build` 在 `build.rs` 生成绑定。
|
|||
|
|
- 本地 smoke(无控制端):`LIBCLANG_PATH=/usr/lib CONFIG_PATH=config/app.yaml cargo run --bin cups_smoke -- --list` / `--print <file> -p <printer>`。
|
|||
|
|
|
|||
|
|
## 原始 proto 文件
|
|||
|
|
路径:`proto/control.proto`
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
syntax = "proto3";
|
|||
|
|
|
|||
|
|
package control.v1;
|
|||
|
|
|
|||
|
|
service Control {
|
|||
|
|
rpc ControlStream(stream ClientMessage) returns (stream ServerMessage);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message ClientMessage {
|
|||
|
|
oneof msg {
|
|||
|
|
Hello hello = 1;
|
|||
|
|
PrintResult result = 2;
|
|||
|
|
Pong pong = 3;
|
|||
|
|
PrinterUpdate printers = 4;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message ServerMessage {
|
|||
|
|
oneof msg {
|
|||
|
|
PrintInstruction print = 1;
|
|||
|
|
Ping ping = 2;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message Hello {
|
|||
|
|
string client_id = 1;
|
|||
|
|
string version = 2;
|
|||
|
|
string hostname = 3;
|
|||
|
|
repeated PrinterInfo printers = 4;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message Ping {
|
|||
|
|
string nonce = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message Pong {
|
|||
|
|
string nonce = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message PrintInstruction {
|
|||
|
|
string request_id = 1;
|
|||
|
|
bytes pdf_data = 2;
|
|||
|
|
PrintParams params = 3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message PrintParams {
|
|||
|
|
uint32 copies = 1;
|
|||
|
|
string duplex = 2; // one_sided, long_edge, short_edge
|
|||
|
|
string color = 3; // auto, color, monochrome
|
|||
|
|
string media = 4;
|
|||
|
|
string quality = 5; // draft, normal, high
|
|||
|
|
string orientation = 6; // portrait, landscape
|
|||
|
|
string job_name = 7;
|
|||
|
|
string printer = 8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message PrintResult {
|
|||
|
|
string request_id = 1;
|
|||
|
|
bool ok = 2;
|
|||
|
|
string printer = 3;
|
|||
|
|
string message = 4;
|
|||
|
|
uint32 retries_used = 5;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message PrinterUpdate {
|
|||
|
|
repeated PrinterInfo printers = 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
message PrinterInfo {
|
|||
|
|
string id = 1;
|
|||
|
|
string name = 2;
|
|||
|
|
string host = 3;
|
|||
|
|
string uri = 4;
|
|||
|
|
string state = 5;
|
|||
|
|
bool accepting_jobs = 6;
|
|||
|
|
bool color_supported = 7;
|
|||
|
|
uint32 active_jobs = 8;
|
|||
|
|
uint32 ppm = 9;
|
|||
|
|
uint32 ppm_color = 10;
|
|||
|
|
repeated string reasons = 11;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|