Skip to content

C# 传输 API ​

在 NNRP SDK 术语中,transport provider 是 NNRP framing/runtime 语义下方的 carrier 边界。它 可以使用传输层协议、WebSocket 这样的应用层 carrier,或本地 IPC;这里的 transport 不会重新 定义 OSI transport layer。

NnrpEndpoint ​

NnrpEndpoint.Parse(string) 只接受用户侧 nnrp:// 和 nnrps:// endpoint。不可变值保留 Authority、PathAndQuery 和 IsSecure,并拒绝 credential、fragment、缺失 authority 和 carrier scheme。

角色 API 接受 NnrpEndpoint;选择 IPC 或 WebSocket 不会迫使应用配置改写 NNRP scheme。

NnrpProviderEndpoint ​

NnrpProviderEndpoint.Parse(string) 表示显式 carrier-local override,由各 provider 包校验自己 拥有的 locator:

Provider接受的 locator
TCPHost 和 port
QUICHost 和 port
Unix IPCunix://
Windows IPCnpipe://
WebSocketws:// 或 wss://

Provider endpoint 用于诊断、conformance 和受控部署。应用代码仍以 NnrpEndpoint 作为逻辑 endpoint,carrier 解析严格遵守以下规则:

  1. 未提供 override 时,TCP 与 QUIC 从应用 authority 派生 host 和 port。
  2. IPC 必须提供匹配的 unix:// 或 npipe:// locator。
  3. WebSocket 必须提供匹配的 ws:// 或 wss:// locator。
  4. 属于其他 provider 的 locator 或与平台不兼容的 IPC locator,必须在 connect、listen 或 probe 创建 native handle 前拒绝。

无法解析的 client route 必须以 RouteUnresolved candidate 保留在诊断中;Auto/Prefer 可以继续选择 其他可用 route,Force 绝不回退。Server Auto/Prefer 下无法解析 route 属于配置错误,因为逻辑 listener set 必须包含全部允许的已安装 provider。

未知 route key 属于无效配置。为已知但未安装的 transport 提供 route 时,必须产生 LocalUnavailable candidate。多个检查同时失败时按协议 rejection registry 顺序选择原因,因此 RouteUnresolved 优先于 SecurityUnsatisfied。

Transport Security ​

类型冻结值
NnrpTransportClientSecurityServerName、owned TrustedCertificateDer
NnrpTransportServerSecurityowned CertificateDer、owned PrivateKeyPkcs8Der

Client security 只能用于 connect/probe,server security 只能用于 listen。QUIC、启用 TLS 的 TCP 与 wss:// 必须提供对应 security。明文 TCP、IPC 与 ws:// 不满足 nnrps:// 应用 endpoint。

Provider Routes ​

类型冻结属性
NnrpClientProviderRouteProviderEndpoint、Security
NnrpServerProviderRouteProviderEndpoint、Security

NnrpClientOptions.ProviderRoutes 与 NnrpServerOptions.ProviderRoutes 是按 TransportId 索引的 只读 dictionary。每条 route 只持有一个 carrier 的 locator 与 security。Role-wide ProviderEndpoint 与 Security 不属于 Preview4 宿主 API。

Provider 契约 ​

csharp
public interface INnrpNativeTransportProvider
{
    NnrpTransportProviderDescriptor Descriptor { get; }

    ValueTask<NnrpTransportConnection> ConnectAsync(
        NnrpTransportConnectOptions options,
        CancellationToken cancellationToken = default);

    ValueTask<NnrpTransportListener> ListenAsync(
        NnrpTransportListenOptions options,
        CancellationToken cancellationToken = default);

    ValueTask<NnrpTransportProbeMetrics> ProbeAsync(
        NnrpTransportProbeOptions options,
        CancellationToken cancellationToken = default);
}

NnrpTransportConnection 和 NnrpTransportListener 是 opaque、可释放的 ownership value。它们 可以把 carrier ownership 转交给角色 runtime,但不会向应用暴露 FFI handle、pointer 或 native buffer。

Options 类型冻结属性
NnrpTransportConnectOptionsEndpoint、ProviderEndpoint、Security、MaxPacketBytes、TimeoutMilliseconds
NnrpTransportListenOptionsEndpoint、ProviderEndpoint、Security、MaxPacketBytes、TimeoutMilliseconds
NnrpTransportProbeOptionsconnect options 加 SampleCount、PayloadBytes、IncludeWarmup

Provider Metadata ​

C# 类型冻结属性或值
NnrpTransportProviderKindPureRust、NativeDynamic、Wasm
NnrpTransportProviderCostModelId: ushort、Units: ulong
NnrpTransportProviderLimitsMaxFrameBytes: ulong
NnrpTransportProviderLimitationRequiresUdp、RequiresTcp、LocalHostOnly、NativeHostOnly、BrowserHostOnly、UnixDomainSocket、WindowsNamedPipe
NnrpTransportProviderMetadataId: string、Cost: NnrpTransportProviderCost、PreferenceRank: ushort、Limits: NnrpTransportProviderLimits、Limitations: IReadOnlyList<NnrpTransportProviderLimitation>
NnrpTransportProviderDescriptorName: string、Version: string、TransportId: TransportId、Kind: NnrpTransportProviderKind、Available: bool、LibraryPath: string?、Metadata: NnrpTransportProviderMetadata、Diagnostic: string?
NnrpTransportCandidateReadinessTransportId: TransportId、ProviderId: string、RouteResolved: bool、SecuritySatisfied: bool、Diagnostic: string?
NnrpTransportProbeStateNotRun、Succeeded、Failed、Missing
NnrpTransportProbeMetricsSampleCount: uint、SuccessCount: uint、MedianThroughputBytesPerSecond: ulong、MedianRttMicroseconds: ulong
NnrpTransportProbeObservationTransportId: TransportId、ProviderId: string、State: NnrpTransportProbeState、Metrics: NnrpTransportProbeMetrics?、Diagnostic: string?;state 只能是 Succeeded 或 Failed
NnrpTransportRejectionReasonPolicyDisallowed、LocalUnavailable、PeerUnsupported、LimitExceeded、RouteUnresolved、SecurityUnsatisfied、ProbeMissing、ProbeFailed
NnrpTransportCandidateTransportId: TransportId、Provider: NnrpTransportProviderMetadata、LocalAvailable: bool、PeerSupported: bool、WithinLimits: bool、ProbeState: NnrpTransportProbeState、Probe: NnrpTransportProbeMetrics?、SelectionRank: uint?、RejectionReason: NnrpTransportRejectionReason?、Diagnostic: string?
NnrpTransportSelectionSelectedProvider: NnrpTransportProviderDescriptor、有序 Candidates: IReadOnlyList<NnrpTransportCandidate>、Policy: TransportPolicy、Diagnostic: string?
NnrpTransportSelectionExceptionCode: NnrpTransportSelectionErrorCode、Policy: TransportPolicy?、TransportId: TransportId?、Candidates: IReadOnlyList<NnrpTransportCandidate>、Diagnostic: string;强制策略失败会标明 transport,InvalidEvidence 在 selection 前发生

NnrpTransportProviderDescriptor.Name 是 provider 自有的 package 名或展示名。Registry lookup、readiness、 selection、route lookup 与 reporting 使用 TransportId,不得从 Name 推导 carrier 身份。

NnrpTransportSelectionOptions 冻结 registry selection 的输入:

属性类型必填说明
PeerSupportedTransportsIReadOnlyCollection<TransportId>是Peer 声明的 carrier 交集。
PolicyTransportPolicy否默认值为 Auto。
RequestedMaxFrameBytesulong?否对照 Provider.Limits.MaxFrameBytes 校验的 workload limit。
CandidateReadinessIReadOnlyCollection<NnrpTransportCandidateReadiness>是每个已注册 provider 的 route/security evidence。
ProbeObservationsIReadOnlyCollection<NnrpTransportProbeObservation>?否按 transport 与 provider identity 匹配的成功/失败 evidence。

PeerSupportedTransports 按集合解释,重复项和枚举顺序不影响选择;RequestedMaxFrameBytes = 0 是合法值, 并且与 null 含义不同。

Metadata 必须与 Rust artifact manifest 一致。C# 使用 Transport Strategy and Probing 冻结的 comparator,不创造 自己的加权分数。

NnrpNativeTransportRegistry ​

方法语义
Register(INnrpNativeTransportProvider)注册一个 provider,拒绝重复 provider 或 transport ID。
Snapshot()返回不可变、稳定顺序的 provider snapshot。
Resolve(NnrpTransportSelectionOptions)执行过滤和选择;没有 provider 可选时抛出携带完整 candidates 的 NnrpTransportSelectionException。

安装的一方包会注册 NnrpNativeTcpTransportProvider、NnrpNativeQuicTransportProvider、 NnrpNativeIpcTransportProvider 或 NnrpNativeWebSocketTransportProvider 到内部默认 registry。 公开角色 options 不接受 provider 实例或 native handle;ProviderRoutes 提供 provider endpoint 意图, TransportPolicy 则约束对已安装包的选择。

只有一个有效 provider 时直接选择;多个有效 provider 才进入冻结的 probe/comparison 路径。 被拒绝的 candidate 仍保留在 NnrpTransportSelection 中。

注册必须拒绝重复 transport ID 与重复 provider metadata ID,且不得替换先注册的 provider。Readiness 与 probe observation 按 (TransportId, ProviderId) 匹配;重复、无法匹配或不完整的 readiness 属于无效输入。 没有匹配 probe observation 表示 Missing,state 为 Failed 的 observation 必须保持为独立失败。

一方包 ​

包具体 Provider持有的产物
Nnrp.Transport.TcpNnrpNativeTcpTransportProvider仅 TCP
Nnrp.Transport.QuicNnrpNativeQuicTransportProvider仅 QUIC
Nnrp.Transport.IpcNnrpNativeIpcTransportProvider仅 IPC
Nnrp.Transport.WebSocketNnrpNativeWebSocketTransportProvider仅 WebSocket

每个包持有自己的具体 provider descriptor 与 transport-scoped Rust artifact。具体 provider 暴露 connect、 listen 与 probe;Nnrp.NativeBridge 统一持有粗粒度 FFI 调用与 native handle 生命周期机制。client 与 server 包不携带 transport artifact。

诊断 Framed Transport ​

INnrpMessageSender、INnrpMessageReceiver、INnrpMessageTransport 和 NnrpTcpMessageTransport 只属于底层 packet 诊断/自定义 carrier 契约。它们不参与生产 provider 选择,也不是 native artifact 缺失时的 fallback。

NNRP Documentation