Rust — 客户端 API
客户端 API 负责启动 transport、打开 runtime session、提交任务、接收事件,并发送控制面更新。核心 metadata 类型见 核心类型。
Dependencies
[dependencies]
nnrp-core = "1.0.0-preview.4.17"
nnrp-runtime = "1.0.0-preview.4.17"
nnrp-transport-tcp = "1.0.0-preview.4.17"
nnrp-transport-quic = "1.0.0-preview.4.17"
nnrp-transport-ipc = "1.0.0-preview.4.17"
nnrp-transport-websocket = "1.0.0-preview.4.17"
tokio = { version = "1", features = ["macros", "rt-multi-thread", "net", "io-util"] }工作流
- 构造
NnrpClientOptions,提供一个应用 endpoint 和一个 provider route set。 - 注册本次部署编译进来的 transport provider。
- 使用
NnrpClient::connect建立连接;Auto/Prefer 会评估全部 eligible provider route。 - 使用
NnrpClient::open_session打开 session。 - 使用
NnrpClientSession::submit提交任务。 - 使用
await_event接收输出和控制事件。 - 使用
close关闭 session。
NnrpClient::connect
let options = NnrpClientOptions {
endpoint: "nnrps://runtime.example/session/default".parse()?,
provider_routes: ClientProviderRoutes::from([
(TransportId::Quic, ClientProviderRoute::native_tls("runtime.example", trusted_certificate_der.clone())),
(TransportId::Tcp, ClientProviderRoute::native_tls("runtime.example", trusted_certificate_der)),
]),
transport_policy: TransportPolicy::Auto,
session: NnrpClientConfig::default(),
};
let client = NnrpClient::connect(
options,
[Arc::new(QuicProvider::default()), Arc::new(TcpProvider::default())],
).await?;NnrpClient::connect 解析并校验每条已安装 route,对全部 eligible Auto/Prefer candidate 执行 probe,最终只把 选中的一个 carrier 接管进返回的 runtime client。Force policy 绝不 fallback。完整 candidate diagnostics 可从 client.transport_selection() 获取。
Rust 显式接收 provider 集合,因为 Cargo dependency 不能在运行时自行注册。每个官方 provider 都实现共享的 client-provider trait;route key 必须与 provider transport ID 一致。
NnrpClientOptions
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
endpoint | NnrpEndpoint | 是 | 用户侧 nnrp:// 或 nnrps:// endpoint。 |
provider_routes | ClientProviderRoutes | 否 | 按 carrier 隔离的 locator 与 peer-security 配置。 |
transport_policy | TransportPolicy | 否 | Auto、Prefer 或 Force policy。 |
session | NnrpClientConfig | 否 | 与 transport 无关的 session 默认值。 |
ClientProviderRoutes 是 BTreeMap<TransportId, ClientProviderRoute>。ClientProviderRoute 精确包含 provider_endpoint: Option<ProviderEndpoint> 与 security: Option<ClientTransportSecurity>。不得把单数 provider endpoint 或一份共享 security 放在 NnrpClientOptions 自身。
ClientTransportSecurity 精确包含 server_name: String 与 trusted_certificate_der: Vec<u8>;两者都必须 非空,证书 bytes 由 security value 持有。提供该值会为 TCP 启用 TLS,QUIC 与 native WSS route 必须提供。
为未安装 provider 的 transport 提供 route 时,该 candidate 保留为 local-unavailable。多个检查同时失败时 按协议 rejection registry 顺序处理,因此 route-unresolved 优先于 security-unsatisfied。
低层 NnrpClient::connect_tcp
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
addr | impl tokio::net::ToSocketAddrs | 是 | Socket address | 目标 TCP endpoint。 |
config | NnrpClientConfig | 是 | 与 transport 无关 | Client runtime 配置。 |
| 返回 | 错误 |
|---|---|
Result<NnrpClient, RuntimeError> | DNS、connect、transport 或配置错误。 |
let config = NnrpClientConfig::default();
let client = NnrpClient::connect_tcp("127.0.0.1:4433", config).await?;这个方法是单数 TCP provider surface,只用于 provider 测试、诊断和受控的单 carrier 部署,不实现 route selection。
Provider Connect
这些单 provider 调用只用于 provider 测试、诊断和受控单 carrier 部署。生产 provider 选择从 NnrpClient::connect 开始。
| Provider | Package | 常用方法 | 说明 |
|---|---|---|---|
TcpProvider | nnrp-transport-tcp | connect(addr, config) | TCP framed transport。 |
QuicProvider | nnrp-transport-quic | connect(endpoint, endpoint_config, config) | QUIC framed transport。 |
IpcProvider | nnrp-transport-ipc | connect(endpoint, config) | Unix socket 或 Windows named pipe。 |
WebSocketProvider | nnrp-transport-websocket | connect(endpoint, config) | 原生 WebSocket binary transport。 |
let config = NnrpClientConfig::default();
let client = IpcProvider::connect("unix:///tmp/nnrp.sock".parse()?, config).await?;NnrpClient::from_transport
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
transport | T: FramedTransport + 'static | 是 | 任意 framed transport | 自定义或 provider 创建的 transport。 |
config | NnrpClientConfig | 是 | 与 transport 无关 | Runtime 配置。 |
| 返回 | 错误 |
|---|---|
Result<NnrpClient, RuntimeError> | Transport kind 不匹配或配置无效。 |
NnrpClient::open_session
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
| 无 | - | - | - | 使用已连接 client 的配置。 |
| 返回 | 错误 |
|---|---|
Result<NnrpClientSession, RuntimeError> | Session open 拒绝或 transport 错误。 |
let mut session = client.open_session().await?;NnrpClientSession::submit
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
request | NnrpSubmitRequest | 是 | 有效 typed submit request | Identity、header context、encoded metadata 与 owned body。 |
| 返回 | 错误 |
|---|---|
Result<u32, RuntimeError> | 序列化、流控、生命周期或 transport 错误。 |
let frame_id = session
.submit(request)
.await?;NnrpClientSession::submit_nowait
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
request | NnrpSubmitRequest | 是 | 有效 typed submit request | Identity、header context、encoded metadata 与 owned body。 |
| 返回 | 错误 |
|---|---|
Result<u32, RuntimeError> | 写入 frame 后返回;结果后续从 event 接收。 |
NnrpClientSession::submit_encoded
这个高级方法接收已编码 submit metadata,并分配下一个 frame id。普通应用应优先使用 profile builder 构造 NnrpSubmitRequest,再调用 submit。
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
metadata | FrameSubmitMetadata | 是 | 有效 submit metadata | Operation metadata。 |
body | Vec<u8> | 是 | 可为空 | 序列化后的请求 body。 |
| 返回 | 错误 |
|---|---|
Result<u32, RuntimeError> | frame 写入后返回分配的 frame id。 |
submit_encoded_nowait 是相同的 encoded 边界,名称明确表达 fire-and-poll 语义。
NnrpClientSession::submit_encoded_with_frame_id
当 embedding 或粗粒度 FFI 边界已经持有 frame identifier 时使用该方法。它执行与 submit_nowait 相同的校验和 carrier 写入,不绕过 session runtime。
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
frame_id | u32 | 是 | 非零且不小于下一个可分配 id | 写入 NNRP common header 的 frame identifier;首次显式 id 可以向前跳号。 |
metadata | FrameSubmitMetadata | 是 | 有效 submit metadata | Operation metadata。 |
body | Vec<u8> | 是 | 可为空 | 序列化后的请求 body。 |
| 返回 | 错误 |
|---|---|
Result<u32, RuntimeError> | frame 写入后返回传入的 id。拒绝零值、复用或回退,失败时不修改当前 allocator。 |
显式提交成功后,session allocator 前进到 frame_id + 1,后续 submit 调用不会复用该 id。 粗粒度 native FFI submit 必须使用这条 canonical 路径;binding 不得自行构造或写出 packet。
NnrpClientSession::await_event
Preview4 应用优先使用这个方法。它返回闭合的 client role-event 联合类型,将普通 wire event 与 不带 header 的本地 operation lifecycle 通知保留为不同 variant。
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
| 无 | - | - | - | 读取下一个 client role event。 |
| 返回 | 错误 |
|---|---|
Result<NnrpClientRoleEvent, RuntimeError> | Transport、解析、生命周期或 unexpected-message 错误。 |
match session.await_event().await? {
NnrpClientRoleEvent::Runtime(NnrpRuntimeEvent {
metadata: NnrpRuntimeEventMetadata::PartialResult(metadata),
tail: NnrpRuntimeEventTail::Body(body),
..
}) => handle_partial(metadata, body),
NnrpClientRoleEvent::Runtime(NnrpRuntimeEvent {
metadata: NnrpRuntimeEventMetadata::Progress(metadata),
tail: NnrpRuntimeEventTail::Body(body),
..
}) => update_progress(metadata, body),
NnrpClientRoleEvent::Runtime(NnrpRuntimeEvent {
metadata: NnrpRuntimeEventMetadata::ResultDropReason(metadata),
tail: NnrpRuntimeEventTail::Diagnostic(body),
..
}) => record_drop(metadata, body),
NnrpClientRoleEvent::Lifecycle(event) => record_lifecycle(event),
_ => {}
}NnrpClientSession::await_result
| 参数 | 类型 | 必填 | 取值范围 | 说明 |
|---|---|---|---|---|
| 无 | - | - | - | 读取下一条 event,并要求它是终态 result。 |
| 返回 | 错误 |
|---|---|
Result<NnrpResult, RuntimeError> | 返回 Success、Cancelled、Dropped 或 Error,不压平终态 event;允许非终态 event 时使用 await_event。 |
Runtime Control Methods
| 方法 | 参数 | 返回 | 说明 |
|---|---|---|---|
cancel_operation | operation_id, reason_code | Result<(), RuntimeError> | 请求取消操作。 |
abort_operation | operation_id, reason_code | Result<(), RuntimeError> | 请求中止操作,语义比 cancel 更强。 |
update_priority | priority metadata | Result<(), RuntimeError> | 更新调度优先级。 |
update_deadline | deadline metadata | Result<(), RuntimeError> | 更新任务 deadline。 |
expire_at | expiration metadata | Result<(), RuntimeError> | 标记任务在指定时间后失效。 |
send_flow_update | flow metadata | Result<(), RuntimeError> | 发送 flow/backpressure 状态。 |
send_credit_update | credit metadata | Result<(), RuntimeError> | 发送可用 credit。 |
send_control_request | message type, metadata | Result<(), RuntimeError> | 通用紧凑控制帧。 |
send_control_request_with_diagnostics | message type, metadata, diagnostics | Result<(), RuntimeError> | 带 trace/diagnostic body 的通用控制帧。 |
这些帧的 wire 定义见 运行时控制 Profiles。
Session Lifecycle Methods
| 方法 | 参数 | 返回 | 说明 |
|---|---|---|---|
patch_session | session patch metadata | Result<SessionPatchAckMetadata, RuntimeError> | 更新 session 参数。 |
migrate_transport | migration metadata | Result<SessionMigrateAckMetadata, RuntimeError> | 请求 transport migration。 |
close | 无 | Result<(), RuntimeError> | 正常关闭 session。 |
close_transport | 无 | Result<(), RuntimeError> | 异常路径关闭 transport。 |
NnrpClientConfig
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
requested_session_id | u32 | 0 | 请求的 session id。 |
profile_id | u16 | 标准 token profile | 请求 profile。 |
schema_id / schema_version | u32 | 标准 registry 值 | Schema identity。 |
priority_class | SessionPriorityClass | Balanced | 调度优先级。 |
default_deadline_ms | u32 | 500 | 默认 operation deadline。 |
max_in_flight_operations | u16 | 4 | 本地 in-flight 限制。 |
lease_ttl_hint_ms | u32 | 30000 | Lease TTL hint。 |
allow_resume | bool | false | 启用恢复语义。 |
cache_hints | Vec<CacheObjectKind> | 空 | Client 预计使用的 cache object kinds。 |
CachePolicyOptions
CachePolicyOptions 是本地显式启用值,不会执行隐式查询或自动发送帧。
| Rust 字段 | 类型 | 默认值 |
|---|---|---|
enabled | bool | false |
reuse_scope | Option<CacheReuseScope> | None |
expiration_hint_ms | u64 | 0 |
invalidation_reason | CachePolicyInvalidationReason | Explicit |
CachePolicyInvalidationReason 包含 Explicit、DependencyInvalidated、LeaseExpired、 VersionMismatch 和 SchemaMismatch。CachePolicyOptions::validate 执行共享校验规则。
NnrpResult
| 字段 | 类型 | 说明 |
|---|---|---|
operation_id | u64 | 非零 submitted operation identity。 |
terminal_state | ResultTerminalState | Success、Cancelled、Dropped 或 Error。 |
event | NnrpTerminalEvent | 闭合的 Runtime(NnrpRuntimeEvent) | Lifecycle(OperationLifecycleEvent) 终态证据。 |
成功结果在 Runtime 变体中保留 RESULT_PUSH。非成功结果保留建立该状态的 wire event 或精确本地 lifecycle event;SDK 不会伪造 wire header 或成功结果 metadata。
OperationLifecycleEvent
| 字段 | 类型 | 说明 |
|---|---|---|
operation_id | u64 | 非零 operation identity。 |
state | OperationState | 精确的本地生命周期状态。 |
这是本地 role 通知,不是 wire event,不携带也不伪造 RuntimeFrameHeader。终态映射固定为 Completed -> Success、Cancelled -> Cancelled、Superseded -> Dropped、Failed -> Error。