// 主机核心初始化代码
hostSDK := host.NewHost(50051) // 初始化Host SDK,监听50051端口
// 注册命令处理器:响应插件的请求,或处理自身下发命令的回调
hostSDK.AddRequestHandler("start", func(pluginID, requestID string, args json.RawMessage) (interface{}, error) {
// 处理start命令逻辑
return map[string]interface{}{"status": "started", "task": "ymtask"}, nil
})
hostSDK.AddRequestHandler("stop", func(pluginID, requestID string, args json.RawMessage) (interface{}, error) {
// 处理stop命令逻辑
return map[string]interface{}{"status": "stopped"}, nil
})
// 启动Host服务(异步执行,避免阻塞)
go func() {
if err := hostSDK.Start(); err != nil {
slog.Error("Host failed", "err", err)
}
}()- 主机创建
<font style="color:rgb(0, 0, 0);">Host</font>实例并指定监听端口(50051); - 注册
<font style="color:rgb(0, 0, 0);">start/stop</font>命令的处理器,用于响应插件的主动调用或处理自身下发命令的反馈; - 异步启动 Host 服务,等待插件连接。
// 插件核心初始化代码
cb := plugin.PluginCallback{
OnShutdown: func() {
slog.Info("plugin shutdown")
},
}
// 初始化Plugin SDK,指定插件信息和主机地址
sdk, err := plugin.NewPlugin(data.Plugin{
ID: "1",
Name: "hello-plugin",
Version: "1.0.0",
ServerAddr: "localhost:50051", // 连接主机的地址
}, cb)
if err != nil {
slog.Error("new plugin error", "error", err)
return
}
defer sdk.Close()
// 注册响应主机下发命令的处理器
sdk.AddRequestHandler("start", func(requestID string, args json.RawMessage) (interface{}, error) {
// 处理主机下发的start命令
return map[string]interface{}{"status": "started", "task": "task"}, nil
})
sdk.AddRequestHandler("stop", func(requestID string, args json.RawMessage) (interface{}, error) {
// 处理主机下发的stop命令
return map[string]interface{}{"status": "stopped"}, nil
})
// 注册处理主机响应的处理器(插件主动调用主机后,接收结果用)
sdk.AddResponseHandler("start", func(requestID string, args json.RawMessage) (interface{}, error) {
// 处理主机对start调用的响应
return map[string]interface{}{"status": "stopped"}, nil
})
sdk.AddResponseHandler("stop", func(requestID string, args json.RawMessage) (interface{}, error) {
// 处理主机对stop调用的响应
return map[string]interface{}{"status": "stopped"}, nil
})- 插件创建
<font style="color:rgb(0, 0, 0);">Plugin</font>实例,指定自身标识(ID / 名称 / 版本)和主机地址; - 注册
<font style="color:rgb(0, 0, 0);">RequestHandler</font>:用于接收并响应主机主动下发的<font style="color:rgb(0, 0, 0);">start/stop</font>命令; - 注册
<font style="color:rgb(0, 0, 0);">ResponseHandler</font>:用于接收主机对插件主动调用的响应结果; - 插件启动后自动连接主机,连接成功后打印
<font style="color:rgb(0, 0, 0);">Plugin started and connected to host</font>。
主机启动 10 秒后,遍历已连接的插件,主动下发<font style="color:rgba(0, 0, 0, 0.85) !important;">start</font>命令:
// 主机定时任务(10秒后执行)
time.AfterFunc(10*time.Second, func() {
plugins := hostSDK.ListPlugins() // 获取已连接的插件列表
for id := range plugins {
// 构造start命令的参数
startRequest := data.StartRequest{}
startRequest.Task = "back"
request, _ := json.Marshal(&startRequest)
// 给插件发送start命令
ch, err := hostSDK.SendCommand(id, "start", request)
if err != nil {
slog.Error("Send command failed", "err", err)
continue
}
// 异步接收插件的响应结果
go func() {
resp := <-ch
if resp.Success {
slog.Info("Command succeeded", "plugin", id, "data", string(resp.Data))
} else {
slog.Error("Command failed", "plugin", id, "error", resp.Error)
}
}()
}
})插件的<font style="color:rgba(0, 0, 0, 0.85) !important;">start</font>命令处理器被触发,处理请求并返回结果:
// 插件的start命令处理器
sdk.AddRequestHandler("start", func(requestID string, args json.RawMessage) (interface{}, error) {
slog.Info("Received 'start' from host", "request_id", requestID, "args", args)
// 返回响应结果给主机
return map[string]interface{}{
"status": "started",
"task": "task",
}, nil
})- 插件打印日志:
<font style="color:rgb(0, 0, 0);">Received 'start' from host request_id=xxx args="{\"task\":\"back\"}"</font>; - 插件将结果序列化后返回给主机,主机接收后打印
<font style="color:rgb(0, 0, 0);">Command succeeded</font>日志。
插件启动 10 秒后,主动调用主机的<font style="color:rgba(0, 0, 0, 0.85) !important;">stop</font>命令:
// 插件定时任务(10秒后执行)
time.AfterFunc(10*time.Second, func() {
go func() {
rawData := json.RawMessage(`{"table": "users"}`) // 构造调用参数
// 调用主机的stop命令
result, err := sdk.CallHost("stop", rawData)
if err != nil {
slog.Error("CallHost failed", "err", err)
} else {
slog.Info("Host returned", "result", result)
}
}()
})主机的<font style="color:rgba(0, 0, 0, 0.85) !important;">stop</font>命令处理器被触发,处理插件的调用请求并返回结果:
// 主机的stop命令处理器
hostSDK.AddRequestHandler("stop", func(pluginID, requestID string, args json.RawMessage) (interface{}, error) {
slog.Info("Host handling 'stop'", "plugin", pluginID, "request_id", requestID)
return map[string]interface{}{"status": "stopped"}, nil
})插件的<font style="color:rgba(0, 0, 0, 0.85) !important;">stop</font>响应处理器被触发,接收主机返回的结果:
// 插件的stop响应处理器
sdk.AddResponseHandler("stop", func(requestID string, args json.RawMessage) (interface{}, error) {
slog.Info("Received 'stop' from host", "request_id", requestID)
return map[string]interface{}{"status": "stopped"}, nil
})- 插件打印日志:
<font style="color:rgb(0, 0, 0);">Received 'stop' from host request_id=xxx</font>; - 插件打印主机返回结果:
<font style="color:rgb(0, 0, 0);">Host returned result="{\"status\":\"stopped\"}"</font>。
主机监听系统退出信号(SIGINT/SIGTERM),收到信号后停止服务:
// 主机终止逻辑
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
hostSDK.Stop() // 停止Host服务,断开与插件的连接插件通过<font style="color:rgba(0, 0, 0, 0.85) !important;">defer sdk.Close()</font>关闭连接。
| API | 作用 |
|---|---|
<font style="color:rgb(0, 0, 0);">host.NewHost(port int)</font> |
初始化 Host 实例,指定监听端口 |
<font style="color:rgb(0, 0, 0);">hostSDK.AddRequestHandler(cmd string, handler)</font> |
注册命令处理器,响应插件的主动调用 |
<font style="color:rgb(0, 0, 0);">hostSDK.Start()</font> |
启动 Host 服务,监听端口等待插件连接 |
<font style="color:rgb(0, 0, 0);">hostSDK.ListPlugins()</font> |
获取已连接的插件列表 |
<font style="color:rgb(0, 0, 0);">hostSDK.SendCommand(pluginID, cmd, args)</font> |
给指定插件下发命令,返回通道接收插件响应 |
<font style="color:rgb(0, 0, 0);">hostSDK.Stop()</font> |
停止 Host 服务 |
| API | 作用 |
|---|---|
<font style="color:rgb(0, 0, 0);">plugin.NewPlugin(pluginInfo, callback)</font> |
初始化 Plugin 实例,指定插件信息和主机地址,设置回调函数 |
<font style="color:rgb(0, 0, 0);">sdk.AddRequestHandler(cmd string, handler)</font> |
注册命令处理器,响应主机下发的命令 |
<font style="color:rgb(0, 0, 0);">sdk.AddResponseHandler(cmd string, handler)</font> |
注册响应处理器,接收主机对插件主动调用的响应结果 |
<font style="color:rgb(0, 0, 0);">sdk.CallHost(cmd string, args)</font> |
主动调用主机的指定命令,返回主机的响应结果 |
<font style="color:rgb(0, 0, 0);">sdk.Close()</font> |
关闭插件与主机的连接 |

