chore: update dependencies and improve bot configuration

- Upgrade Go version to 1.24.0 and update toolchain.
- Update various dependencies in go.mod and go.sum, including:
  - Upgrade `fasthttp/websocket` to v1.5.12
  - Upgrade `fsnotify/fsnotify` to v1.9.0
  - Upgrade `valyala/fasthttp` to v1.58.0
  - Add new dependencies for `bytedance/sonic` and `google/uuid`.
- Refactor bot configuration in config.toml to support multiple bot protocols, including "milky" and "onebot11".
- Modify internal configuration structures to accommodate new bot settings.
- Enhance event dispatcher with metrics tracking and asynchronous processing capabilities.
- Implement WebSocket connection management with heartbeat and reconnection logic.
- Update server handling for bot management and event publishing.
This commit is contained in:
lafay
2026-01-05 00:40:09 +08:00
parent ac0dfb64c9
commit 44fe05ff62
30 changed files with 6311 additions and 182 deletions

View File

@@ -6,6 +6,7 @@ import (
"cellbot/internal/engine"
"cellbot/internal/protocol"
"cellbot/pkg/net"
"go.uber.org/fx"
"go.uber.org/zap"
)
@@ -17,58 +18,59 @@ func RegisterLifecycleHooks(
dispatcher *engine.Dispatcher,
botManager *protocol.BotManager,
server *net.Server,
) fx.Option {
return fx.Invoke(
func(lc fx.Lifecycle) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
logger.Info("Starting CellBot application...")
lc fx.Lifecycle,
) {
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
logger.Info("=== Starting CellBot application ===")
// 启动事件总线
eventBus.Start()
// 启动事件总线
logger.Info("Starting event bus...")
eventBus.Start()
logger.Info("Event bus started")
// 启动分发器
dispatcher.Start(ctx)
// 启动分发器
logger.Info("Starting dispatcher...")
dispatcher.Start(ctx)
logger.Info("Dispatcher started")
// 启动所有机器人
if err := botManager.StartAll(ctx); err != nil {
logger.Error("Failed to start bots", zap.Error(err))
}
// 启动所有机器人
if err := botManager.StartAll(ctx); err != nil {
logger.Error("Failed to start bots", zap.Error(err))
}
// 启动HTTP服务器
if err := server.Start(); err != nil {
logger.Error("Failed to start server", zap.Error(err))
return err
}
// 启动HTTP服务器
if err := server.Start(); err != nil {
logger.Error("Failed to start server", zap.Error(err))
return err
}
logger.Info("CellBot application started successfully")
return nil
},
OnStop: func(ctx context.Context) error {
logger.Info("Stopping CellBot application...")
// 停止HTTP服务器
if err := server.Stop(); err != nil {
logger.Error("Failed to stop server", zap.Error(err))
}
// 停止所有机器人
if err := botManager.StopAll(ctx); err != nil {
logger.Error("Failed to stop bots", zap.Error(err))
}
// 停止分发器
dispatcher.Stop()
// 停止事件总线
eventBus.Stop()
logger.Info("CellBot application stopped successfully")
return nil
},
})
logger.Info("CellBot application started successfully")
return nil
},
)
OnStop: func(ctx context.Context) error {
logger.Info("Stopping CellBot application...")
// 停止HTTP服务器
if err := server.Stop(); err != nil {
logger.Error("Failed to stop server", zap.Error(err))
}
// 停止所有机器人
if err := botManager.StopAll(ctx); err != nil {
logger.Error("Failed to stop bots", zap.Error(err))
}
// 停止分发器
dispatcher.Stop()
// 停止事件总线
eventBus.Stop()
logger.Info("CellBot application stopped successfully")
return nil
},
})
}
// Lifecycle 生命周期管理选项

View File

@@ -1,20 +1,23 @@
package di
import (
"cellbot/internal/adapter/milky"
"cellbot/internal/adapter/onebot11"
"cellbot/internal/config"
"cellbot/internal/engine"
"cellbot/internal/plugins/echo"
"cellbot/internal/protocol"
"cellbot/pkg/net"
"context"
"go.uber.org/fx"
"go.uber.org/zap"
)
// ProvideLogger 提供日志实例
func ProvideLogger(cfg *config.Config) (*zap.Logger, error) {
return config.InitLogger(&cfg.Log)
}
// ProvideConfig 提供配置实例
func ProvideConfig() (*config.Config, error) {
configManager := config.NewConfigManager("configs/config.toml", zap.NewNop())
if err := configManager.Load(); err != nil {
@@ -23,40 +26,115 @@ func ProvideConfig() (*config.Config, error) {
return configManager.Get(), nil
}
// ProvideConfigManager 提供配置管理器
func ProvideConfigManager(logger *zap.Logger) (*config.ConfigManager, error) {
configManager := config.NewConfigManager("configs/config.toml", logger)
if err := configManager.Load(); err != nil {
return nil, err
}
// 启动配置文件监听
if err := configManager.Watch(); err != nil {
logger.Warn("Failed to watch config file", zap.Error(err))
}
return configManager, nil
}
// ProvideEventBus 提供事件总线
func ProvideEventBus(logger *zap.Logger) *engine.EventBus {
return engine.NewEventBus(logger, 10000)
}
// ProvideDispatcher 提供事件分发器
func ProvideDispatcher(eventBus *engine.EventBus, logger *zap.Logger) *engine.Dispatcher {
return engine.NewDispatcher(eventBus, logger)
}
// ProvideBotManager 提供机器人管理器
func ProvideBotManager(logger *zap.Logger) *protocol.BotManager {
return protocol.NewBotManager(logger)
}
// ProvideServer 提供HTTP服务器
func ProvideWebSocketManager(logger *zap.Logger, eventBus *engine.EventBus) *net.WebSocketManager {
return net.NewWebSocketManager(logger, eventBus)
}
func ProvideServer(cfg *config.Config, logger *zap.Logger, botManager *protocol.BotManager, eventBus *engine.EventBus) *net.Server {
return net.NewServer(cfg.Server.Host, cfg.Server.Port, logger, botManager, eventBus)
}
// Providers 依赖注入提供者列表
func ProvideMilkyBots(cfg *config.Config, logger *zap.Logger, eventBus *engine.EventBus, wsManager *net.WebSocketManager, botManager *protocol.BotManager, lc fx.Lifecycle) error {
for _, botCfg := range cfg.Bots {
if botCfg.Protocol == "milky" && botCfg.Enabled {
logger.Info("Creating Milky bot", zap.String("bot_id", botCfg.ID))
milkyCfg := &milky.Config{
ProtocolURL: botCfg.Milky.ProtocolURL,
AccessToken: botCfg.Milky.AccessToken,
EventMode: botCfg.Milky.EventMode,
WebhookListenAddr: botCfg.Milky.WebhookListenAddr,
Timeout: botCfg.Milky.Timeout,
RetryCount: botCfg.Milky.RetryCount,
}
bot := milky.NewBot(botCfg.ID, milkyCfg, eventBus, wsManager, logger)
botManager.Add(bot)
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
logger.Info("Starting Milky bot", zap.String("bot_id", botCfg.ID))
return bot.Connect(ctx)
},
OnStop: func(ctx context.Context) error {
logger.Info("Stopping Milky bot", zap.String("bot_id", botCfg.ID))
return bot.Disconnect(ctx)
},
})
}
}
return nil
}
func ProvideOneBot11Bots(cfg *config.Config, logger *zap.Logger, wsManager *net.WebSocketManager, eventBus *engine.EventBus, botManager *protocol.BotManager, lc fx.Lifecycle) error {
for _, botCfg := range cfg.Bots {
if botCfg.Protocol == "onebot11" && botCfg.Enabled {
logger.Info("Creating OneBot11 bot", zap.String("bot_id", botCfg.ID))
ob11Cfg := &onebot11.Config{
ConnectionType: botCfg.OneBot11.ConnectionType,
Host: botCfg.OneBot11.Host,
Port: botCfg.OneBot11.Port,
AccessToken: botCfg.OneBot11.AccessToken,
WSUrl: botCfg.OneBot11.WSUrl,
WSReverseUrl: botCfg.OneBot11.WSReverseUrl,
Heartbeat: botCfg.OneBot11.Heartbeat,
ReconnectInterval: botCfg.OneBot11.ReconnectInterval,
HTTPUrl: botCfg.OneBot11.HTTPUrl,
HTTPPostUrl: botCfg.OneBot11.HTTPPostUrl,
Secret: botCfg.OneBot11.Secret,
Timeout: botCfg.OneBot11.Timeout,
SelfID: botCfg.OneBot11.SelfID,
Nickname: botCfg.OneBot11.Nickname,
}
bot := onebot11.NewBot(botCfg.ID, ob11Cfg, logger, wsManager, eventBus)
botManager.Add(bot)
lc.Append(fx.Hook{
OnStart: func(ctx context.Context) error {
logger.Info("Starting OneBot11 bot", zap.String("bot_id", botCfg.ID))
return bot.Connect(ctx)
},
OnStop: func(ctx context.Context) error {
logger.Info("Stopping OneBot11 bot", zap.String("bot_id", botCfg.ID))
return bot.Disconnect(ctx)
},
})
}
}
return nil
}
func ProvideEchoPlugin(logger *zap.Logger, botManager *protocol.BotManager, dispatcher *engine.Dispatcher) {
echoPlugin := echo.NewEchoPlugin(logger, botManager)
dispatcher.RegisterHandler(echoPlugin)
logger.Info("Echo plugin registered")
}
var Providers = fx.Options(
fx.Provide(
ProvideConfig,
@@ -65,6 +143,10 @@ var Providers = fx.Options(
ProvideEventBus,
ProvideDispatcher,
ProvideBotManager,
ProvideWebSocketManager,
ProvideServer,
),
fx.Invoke(ProvideMilkyBots),
fx.Invoke(ProvideOneBot11Bots),
fx.Invoke(ProvideEchoPlugin),
)