跳到主要内容

快速入门

本指南将引导您为 YedMQ 创建一个简单的“Hello World”插件。我们将使用 Python 作为此示例,但您可以使用任何支持 Unix 套接字或命名管道的语言。

目标是创建一个处理客户端认证钩子的插件,在客户端尝试连接时打印一条消息。

1. 项目结构

首先,为您的插件创建一个文件夹。您所有的插件文件,包括可执行文件和配置,都将存储在这里。

|- my-first-plugin/
| |- plugin.toml
| |- main.py

2. 插件配置 (plugin.toml)

此文件告诉 YedMQ 如何运行您的插件。创建一个包含以下内容的 plugin.toml 文件:

[plugin]
name = "my-first-plugin"
author = "你的名字"
description = "一个简单的示例插件"
version = "0.0.1"
priority = 1000

[runtime]
type = "process"
# 此命令假定您从项目的根目录运行代理。
# 'python3' 应该在您系统的 PATH 中。
executable = "python3"
args = ["my-first-plugin/main.py"]
  • executable: 我们将其设置为 python3 来运行我们的脚本。
  • args: 我们将 Python 脚本的路径作为参数传递。

3. 插件脚本 (main.py)

插件的核心是可执行脚本。该脚本需要:

  1. 解析命令行参数以获取 --auth-code--socket-path
  2. 连接到代理提供的 IPC 套接字。
  3. 处理 Initialize 请求/响应握手。
  4. 监听传入的消息(钩子)并对其进行响应。

这是一个使用 Python 的简化示例。请注意,在实际场景中,您将使用 Protobuf 库生成用于消息序列化和反序列化的代码。为简单起见,本示例将侧重于逻辑,并对 Protobuf 处理使用伪代码。

# main.py
import socket
import sys
import argparse
import time

# 在实际实现中,您将使用生成的 Protobuf 类。
# from your_generated_protobuf_files import ProtocolMessage, InitializeRequest, InitializeResponse

def main():
parser = argparse.ArgumentParser()
parser.add_argument("--auth-code", required=True, help="来自 YedMQ 代理的安全令牌")
parser.add_argument("--socket-path", required=True, help="IPC 套接字的路径")
args = parser.parse_args()

auth_code = args.auth_code
socket_path = args.socket_path

# 1. 连接到套接字
# 在 Linux/macOS 上,这将是一个 Unix 域套接字。
# 在 Windows 上,您将使用一个库来连接到命名管道。
client_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
try:
client_socket.connect(socket_path)
except socket.error as msg:
# 您应该将错误写入 stderr 以便代理捕获
sys.stderr.write(f"无法连接到套接字: {msg}\n")
sys.exit(1)

# 2. 执行初始化握手
# 这是一个简化的表示。您必须构建一个正确的
# 二进制帧(魔数 + 版本 + 长度 + 有效载荷)。

# 首先,代理发送一个 InitializeRequest
# 我们需要从套接字读取消息。
# raw_request = read_protocol_message(client_socket)
# request_message = ProtocolMessage.FromString(raw_request)

# 假设我们收到了 InitializeRequest。现在,我们发送一个响应。
# initialize_response = InitializeResponse(
# status="ready",
# capabilities=["authentication"],
# hooks=[Hook(name="authenticate", priority=100)],
# auth_code=auth_code # 重要:发回 auth_code
# )
# response_message = ProtocolMessage(
# type=MESSAGE_TYPE_RESPONSE,
# id="some-uuid",
# result=Any.pack(initialize_response)
# )
# send_protocol_message(client_socket, response_message)

# 对于这个简单的例子,我们只记录我们“已初始化”
sys.stdout.write("插件初始化成功(模拟)。\n")
sys.stdout.flush()


# 3. 主循环处理传入的钩子调用
while True:
# 在一个真正的插件中,你会不断地从套接字中读取
# 来自代理的新消息。

# raw_message = read_protocol_message(client_socket)
# message = ProtocolMessage.FromString(raw_message)

# if message.method == METHOD_AUTHENTICATE:
# auth_request = AuthenticateRequest()
# message.params.Unpack(auth_request)
# print(f"收到客户端的认证请求: {auth_request.client_id}")

# # 响应认证成功
# auth_response = AuthenticateResponse(authenticated=True, tenant_id="default")
# response = ProtocolMessage(...)
# send_protocol_message(client_socket, response)

# 这是一个占位符循环
time.sleep(10)


if __name__ == "__main__":
# 添加一个小延迟来模拟启动工作
time.sleep(1)
main()

注意: 上述代码是一个概念性说明。一个真正的实现需要:

  • 适用于您语言的 Protobuf 库,以从 .proto 定义生成代码。有关完整的架构和源文件位置,请参阅 协议定义 页面。
  • 一个健壮的实现,用于向套接字读写二进制协议帧。

4. 部署插件

要部署插件,您需要将其文件夹放置在 YedMQ 的 plugins 目录中。

假设您的 YedMQ 安装在 /opt/yedmq,结构将如下所示:

/opt/yedmq/
├── plugins/
│ └── my-first-plugin/
│ ├── plugin.toml
│ └── main.py
└── ... (其他 YedMQ 文件)

5. 启动 YedMQ

现在,启动 YedMQ 代理。如果一切配置正确,代理将会:

  1. 读取 my-first-plugin/plugin.toml
  2. 执行 python3 my-first-plugin/main.py --auth-code ... --socket-path ...
  3. 建立 IPC 连接。
  4. 执行初始化握手。
  5. 您的插件现在正在运行并准备好接收钩子调用。

您应该在代理的日志中看到“插件初始化成功(模拟)”的消息(或您重定向插件 stdout 的任何地方)。当客户端连接时,您的插件的 METHOD_AUTHENTICATE 处理程序将被调用。