feat(ws): implement WebSocket cluster mode with Redis Pub/Sub
All checks were successful
Build Backend / build (push) Successful in 2m0s
Build Backend / build-docker (push) Successful in 1m26s

Introduce a new WebSocket messaging architecture that supports both standalone and cluster modes. This allows for horizontal scaling of WebSocket servers by using Redis Pub/Sub to synchronize messages across multiple instances.

Key changes:
- Added `ws.MessagePublisher` interface to abstract message distribution.
- Implemented `ws.Bus` to handle cluster-mode messaging via Redis.
- Added `ws.OnlineTracker` to manage user online status across the cluster.
- Refactored multiple services (Chat, Group, Push, Call, etc.) to use the new `MessagePublisher` instead of a concrete `ws.Hub`.
- Added WebSocket configuration options (mode, instance ID, channel, TTL, heartbeat) to `config.yaml` and `config.go`.
- Updated dependency injection with Wire to support the new publisher and Redis client.
- Improved logging by replacing standard `log` with `zap` in several service components.
This commit is contained in:
2026-05-06 12:39:11 +08:00
parent d481742790
commit c630cbf4d0
22 changed files with 1082 additions and 120 deletions

View File

@@ -25,7 +25,7 @@ type App struct {
HotRankWorker *service.HotRankWorker
GRPCServer *runner.Server
Server *http.Server
WsHub *ws.Hub
Publisher ws.MessagePublisher
Logger *zap.Logger
}
@@ -37,7 +37,7 @@ func NewApp(
pushService service.PushService,
hotRankWorker *service.HotRankWorker,
grpcServer *runner.Server,
wsHub *ws.Hub,
publisher ws.MessagePublisher,
logger *zap.Logger,
) *App {
return &App{
@@ -47,7 +47,7 @@ func NewApp(
PushService: pushService,
HotRankWorker: hotRankWorker,
GRPCServer: grpcServer,
WsHub: wsHub,
Publisher: publisher,
Logger: logger,
}
}
@@ -102,9 +102,14 @@ func (a *App) Stop(ctx context.Context) error {
a.Logger.Info("Shutting down server")
// 1. 关闭所有 WebSocket 连接
if a.WsHub != nil {
if a.Publisher != nil {
a.Logger.Info("Closing WebSocket connections")
a.WsHub.CloseAllConnections()
switch p := a.Publisher.(type) {
case *ws.Bus:
p.Close()
case *ws.Hub:
p.CloseAllConnections()
}
}
// 3. 停止 HTTP 服务器