跳转到主要内容
消息提供在同一内核中运行的插件之间的同步点对点通信。 发送插件指定一个目标插件, 发送一个主题和一个字节有效负载,并等待目标返回回复。 当一个插件需要另一个插件执行操作或返回数据时,请使用消息。 当数据应该作为状态共享而不是作为请求传递时,请使用 KV 存储

消息信封

消息是 PluginMessage,由 Protobuf 契约定义: 目标接收 PluginMessageReply 内核不会解析 topicpayloadmessage。请在参与的插件之间定义它们的格式。 您可以使用 JSON、Protobuf、文本或其他编码,但发送方和目标必须就此达成一致。

发送消息

要发送消息:
  1. 选择目标插件的注册名称;
  2. 选择一个稳定的主题名称;
  3. 将请求编码为 payload;以及
  4. 通过为后端生成的主机绑定发送信封。
发送方等待内核将消息分发给目标插件的消息处理程序。 成功的回复包含目标的 message 值。 源插件无法选择或覆盖其身份;内核会将 source 字段替换为调用插件的已验证名称。

接收消息

目标插件收到相同的信封,包括内核提供的 source。它应该:
  1. 验证源插件是否有权请求此操作;
  2. topic 路由消息;
  3. 解码并验证 payload;以及
  4. 返回结果或错误。
内核不提供主题订阅或插件内部的自动分发功能。 目标插件的消息处理程序接收该插件的消息,并负责解析主题。

错误和传递

消息仅传递给当前正在运行的目标插件。发送失败的情况包括:
  • target 为空;
  • 目标插件未运行;
  • 目标处理程序返回传输或执行错误;或
  • 目标回复包含非空的 error 字段。
目标的 error 值将作为错误返回给发送方。当目标不可用时,消息不会 传递给其他插件。 消息不会被排队、重试、广播或持久化。没有持久传递保证。 如果目标在消息传输过程中停止,调用上下文将随着目标插件的生命周期结束而被取消。

后端行为

两种插件后端的消息语义相同:
  • WASM 插件通过生成的主机绑定发送消息;并且
  • gRPC 插件通过内核的主机回调通道发送请求。
然后,内核通过目标插件选择的后端调用该插件,并将目标插件的响应转换回发送方后端特定的响应类型。

身份和授权

内核在主机边界对源插件进行身份验证。 插件不能通过在发送请求中写入不同的 source 值来冒充其他插件。 没有针对单个主题的内核级访问策略。任何正在运行的插件都可以通过名称寻址其他正在运行的插件, 因此,当主题或有效负载表示特权操作时,目标插件必须在其自身的处理程序中强制执行授权。 将 topic 视为路由信息,而不是访问控制机制。

设计消息契约

保持消息契约的明确性和版本控制:
记录每个主题的有效负载模式、必需字段、响应格式和错误含义。 在使用不受信任的有效负载之前对其进行验证, 对于未知或格式错误的主题,返回明确的错误。 使用稳定的目标名称和主题命名空间。 如果请求可以安全地重复执行,则确保操作幂等,因为在目标暂时失效后, 发送方可能需要在应用程序级别重试。