XiHan Framework 处于预览阶段

查看获取方式
跳转到内容

XiHan.Framework.Plugins.Protocol ​

插件协议 xihan.plugin.v1(RFC-0017)的 .NET 类型:端点与握手行、版本协商、环境变量名、PLUGINS_* 错误码与消息键。进程外宿主、Wasm 宿主与插件一致性套件共用它,应用通常不直接引用。

项内容
包 IDXiHan.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。

安装与启用 ​

bash
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 的环境变量常量:

常量环境变量
ProtocolVersionsVariableXIHAN_PLUGIN_PROTOCOL_VERSIONS
PrimitivesVariableXIHAN_PLUGIN_PRIMITIVES
SessionVariableXIHAN_PLUGIN_SESSION
HostAddressVariableXIHAN_PLUGIN_HOST_ADDRESS
InstanceVariableXIHAN_PLUGIN_INSTANCE
LocaleVariableXIHAN_PLUGIN_LOCALE

使用示例 ​

解析插件写到 stdout 的握手行并协商版本:

csharp
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);

按错误码区分插件不可用与业务失败:

csharp
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):

常量错误码含义
InvalidSourcePLUGINS_VALIDATION_001插件清单、种类或隔离级别不合法,或缺少 entry,或进程外插件的清单写了 contributes.pipeline(只有 Wasm 插件能贡献中间件)
InvalidHandshakePLUGINS_VALIDATION_003握手行不合法,或协议版本没有交集
HandshakeMismatchPLUGINS_VALIDATION_004握手响应与清单不一致:原语层版本、清单字段、未声明或重复的操作 / 健康项 / 订阅(同一主题与类型以两种方式各声明一次也算重复)、订阅方式 mode 不是空 / competing / broadcast,重启后的声明与首次不同
InvalidModulePLUGINS_VALIDATION_005Wasm 模块不合法(不是 reactor、ABI 版本不支持、缺少必需导出或签名不符、导入了宿主不提供的函数)
NotFoundPLUGINS_NOTFOUND_001插件目录、清单或可执行文件不存在,或插件未加载
PermissionDeniedPLUGINS_DENIED_001插件声明的权限未被宿主授予
CallbackDeniedPLUGINS_DENIED_002插件回调的会话令牌无效,或所需权限未在清单声明、未被授予
AlreadyLoadedPLUGINS_CONFLICT_001同一清单 ID 的插件已加载
UnavailablePLUGINS_UNAVAILABLE_001插件未就绪、正在停止、已退出或不可达;Wasm 中间件失败即关闭
ResourceExhaustedPLUGINS_UNAVAILABLE_002Wasm 沙箱资源不足:回调嵌套超限、客体内存分配失败
HostUnsupportedPLUGINS_UNAVAILABLE_003宿主进程不满足载体要求:Windows 强制用户态影子栈时 Wasm 陷阱会终止进程
TimeoutPLUGINS_TIMEOUT_001握手、配置、启动或停止超时
UnexpectedPLUGINS_UNEXPECTED_001配置、启动、停止或调用时发生未预期的失败
CrashedPLUGINS_UNEXPECTED_002插件进程异常退出,或 Wasm 实例陷阱、导出函数返回 0

PLUGINS_UNAVAILABLE_003 是配置错误,以 FrameworkException 抛出、不本地化;其余错误以 Result 返回,文案按调用方区域翻译。进程内宿主有自己的一组错误码常量,见 Plugins.InProcess。

相关 ​

Released under The MIT License