XiHan.Framework.Plugins.Protocol
插件协议 xihan.plugin.v1(RFC-0017)的 .NET 类型:端点与握手行、版本协商、环境变量名、PLUGINS_* 错误码与消息键。进程外宿主、Wasm 宿主与插件一致性套件共用它,应用通常不直接引用。
| 项 | 内容 |
|---|---|
| 包 ID | XiHan.Framework.Plugins.Protocol |
| 环层 | Ring 3(实现) |
| 能力 | — |
| 特性入口 | — |
| 配置节 | — |
| 依赖 | XiHan.Framework.Kernel、XiHan.Framework.Messaging.Abstractions、XiHan.Framework.Localization.Abstractions;Google.Protobuf、Grpc.Core.Api(Grpc.Tools 只在构建期) |
| AOT | 不兼容(Google.Protobuf 的描述符反射未声明裁剪兼容) |
| 稳定性 | Preview |
概述
协议消息与 gRPC 桩由规范里的同一份 spec/plugin/plugin.proto 在构建期生成,生成的类型是 internal,不进公开面。握手核对(HandshakeValidator)、上下文与 InvocationMetadata 的映射、Error / Result 与协议状态的映射、消息信封映射、代理操作描述符、插件贡献的登记(清单声明的权限码与代理操作一次登记,ADR-0080)这些载体无关的部分也在本包,经 InternalsVisibleTo 只给 Plugins.OutOfProcess、Plugins.Wasm、Plugins.Conformance 使用。
公开的只有协议常量与端点类型:写 .NET 宿主扩展、诊断工具或测试时可以用它们解析握手行、协商版本、按错误码判断插件失败。用 .NET 写进程外插件不需要引用本包,插件只要从 plugin.proto 生成自己的桩(见 samples/EchoPlugin)。
何时使用
- 应用只用插件:不直接引用,
Plugins.OutOfProcess或Plugins.Wasm会带上它。 - 要按错误码区分插件失败(如把
PLUGINS_UNAVAILABLE_001映射成重试):引用本包,用PluginErrors的常量,不手写字符串。 - 写插件宿主之外的工具(握手行检查、端点解析):用
PluginEndpoint与PluginProtocol。
安装与启用
dotnet add package XiHan.Framework.Plugins.Protocol --prerelease当前是预览版,安装要带 --prerelease;从源码或本地包源引用见快速上手。本包没有特性入口;两个插件宿主特性在 Configure 时自己登记消息目录 PluginMessages.Catalog(目录名 plugins.protocol,10 种区域各一个文件)。
主要类型
| 类型 | 说明 |
|---|---|
PluginEndpoint | 本机 gRPC 端点:Network(unix / tcp / npipe)与 Address;tcp 只接受带端口的回环地址。TryParseHandshakeLine 解析握手行,TryParse 解析环境变量形式 <network> <address>,ToHandshakeLine() 生成握手行 |
PluginProtocol | 协议版本 Version(1)与 SupportedVersions、版本协商 Negotiate、会话元数据键 SessionMetadataKey(xihan-plugin-session)、错误码尾部元数据键 ErrorCodeTrailer(xihan-error-code)、六个环境变量名 |
PluginErrors | 进程外与 Wasm 载体共用的 PLUGINS_* 错误码常量 |
PluginMessages | 对应的消息键常量与消息目录 Catalog |
PluginProtocol 的环境变量常量:
| 常量 | 环境变量 |
|---|---|
ProtocolVersionsVariable | XIHAN_PLUGIN_PROTOCOL_VERSIONS |
PrimitivesVariable | XIHAN_PLUGIN_PRIMITIVES |
SessionVariable | XIHAN_PLUGIN_SESSION |
HostAddressVariable | XIHAN_PLUGIN_HOST_ADDRESS |
InstanceVariable | XIHAN_PLUGIN_INSTANCE |
LocaleVariable | XIHAN_PLUGIN_LOCALE |
使用示例
解析插件写到 stdout 的握手行并协商版本:
using XiHan.Framework.Plugins.Protocol;
using XiHan.Framework.Plugins.Protocol.Handshake;
if (PluginEndpoint.TryParseHandshakeLine("xihan-plugin/1 tcp 127.0.0.1:50123", out var endpoint))
{
Console.WriteLine($"{endpoint.Network} {endpoint.Address}");
}
// 非回环的 TCP 地址不是合法端点
Console.WriteLine(PluginEndpoint.TryParseHandshakeLine("xihan-plugin/1 tcp 10.0.0.5:50123", out _));
// 取双方都支持的最高版本;没有交集为无值
var negotiated = PluginProtocol.Negotiate(PluginProtocol.SupportedVersions, [1u, 2u]);
Console.WriteLine(negotiated.HasValue);按错误码区分插件不可用与业务失败:
using XiHan.Framework.Plugins.Protocol;
using XiHan.Framework.Primitives;
static bool IsTransient(Error error)
=> error.Code is PluginErrors.Unavailable or PluginErrors.Crashed;行为与限制
错误码全集(spec/conventions/error-codes.md):
| 常量 | 错误码 | 含义 |
|---|---|---|
InvalidSource | PLUGINS_VALIDATION_001 | 插件清单、种类或隔离级别不合法,或缺少 entry,或进程外插件的清单写了 contributes.pipeline(只有 Wasm 插件能贡献中间件) |
InvalidHandshake | PLUGINS_VALIDATION_003 | 握手行不合法,或协议版本没有交集 |
HandshakeMismatch | PLUGINS_VALIDATION_004 | 握手响应与清单不一致:原语层版本、清单字段、未声明或重复的操作 / 健康项 / 订阅(同一主题与类型以两种方式各声明一次也算重复)、订阅方式 mode 不是空 / competing / broadcast,重启后的声明与首次不同 |
InvalidModule | PLUGINS_VALIDATION_005 | Wasm 模块不合法(不是 reactor、ABI 版本不支持、缺少必需导出或签名不符、导入了宿主不提供的函数) |
NotFound | PLUGINS_NOTFOUND_001 | 插件目录、清单或可执行文件不存在,或插件未加载 |
PermissionDenied | PLUGINS_DENIED_001 | 插件声明的权限未被宿主授予 |
CallbackDenied | PLUGINS_DENIED_002 | 插件回调的会话令牌无效,或所需权限未在清单声明、未被授予 |
AlreadyLoaded | PLUGINS_CONFLICT_001 | 同一清单 ID 的插件已加载 |
Unavailable | PLUGINS_UNAVAILABLE_001 | 插件未就绪、正在停止、已退出或不可达;Wasm 中间件失败即关闭 |
ResourceExhausted | PLUGINS_UNAVAILABLE_002 | Wasm 沙箱资源不足:回调嵌套超限、客体内存分配失败 |
HostUnsupported | PLUGINS_UNAVAILABLE_003 | 宿主进程不满足载体要求:Windows 强制用户态影子栈时 Wasm 陷阱会终止进程 |
Timeout | PLUGINS_TIMEOUT_001 | 握手、配置、启动或停止超时 |
Unexpected | PLUGINS_UNEXPECTED_001 | 配置、启动、停止或调用时发生未预期的失败 |
Crashed | PLUGINS_UNEXPECTED_002 | 插件进程异常退出,或 Wasm 实例陷阱、导出函数返回 0 |
PLUGINS_UNAVAILABLE_003 是配置错误,以 FrameworkException 抛出、不本地化;其余错误以 Result 返回,文案按调用方区域翻译。进程内宿主有自己的一组错误码常量,见 Plugins.InProcess。
相关
- 插件
- Plugins.OutOfProcess、Plugins.Wasm、Conformance 一致性套件
- 规范:RFC-0017《进程外插件协议》、RFC-0018《Wasm 插件 ABI》
