feat(websocket): integrate WebSocket support and refactor SSE handling
All checks were successful
Build Backend / build (push) Successful in 18m57s
Build Backend / build-docker (push) Successful in 1m4s

- Added WebSocket support by introducing a new WSHandler and related infrastructure.
- Replaced SSE implementations with WebSocket equivalents across message and QR code handlers.
- Updated service and repository layers to utilize WebSocket for real-time messaging.
- Removed obsolete SSE hub and related code, streamlining the application for WebSocket usage.
- Enhanced router to include WebSocket endpoints for real-time communication.
This commit is contained in:
lafay
2026-03-26 21:17:49 +08:00
parent c6848aba06
commit 6d335e393d
19 changed files with 1277 additions and 315 deletions

View File

@@ -8,7 +8,7 @@ import (
"carrot_bbs/internal/dto"
"carrot_bbs/internal/model"
"carrot_bbs/internal/pkg/sse"
"carrot_bbs/internal/pkg/ws"
"carrot_bbs/internal/repository"
)
@@ -65,7 +65,7 @@ type pushServiceImpl struct {
pushRepo repository.PushRecordRepository
deviceRepo repository.DeviceTokenRepository
messageRepo repository.MessageRepository
sseHub *sse.Hub
wsHub *ws.Hub
// 推送队列
pushQueue chan *pushTask
@@ -84,13 +84,13 @@ func NewPushService(
pushRepo repository.PushRecordRepository,
deviceRepo repository.DeviceTokenRepository,
messageRepo repository.MessageRepository,
sseHub *sse.Hub,
wsHub *ws.Hub,
) PushService {
return &pushServiceImpl{
pushRepo: pushRepo,
deviceRepo: deviceRepo,
messageRepo: messageRepo,
sseHub: sseHub,
wsHub: wsHub,
pushQueue: make(chan *pushTask, PushQueueSize),
stopChan: make(chan struct{}),
}
@@ -138,7 +138,7 @@ func (s *pushServiceImpl) PushToUser(ctx context.Context, userID string, message
// pushViaWebSocket 通过WebSocket推送消息
// 返回true表示推送成功false表示用户不在线
func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, message *model.Message) bool {
if s.sseHub == nil || !s.sseHub.HasSubscribers(userID) {
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
return false
}
@@ -174,7 +174,7 @@ func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, m
}
}
}
s.sseHub.PublishToUser(userID, "system_notification", notification)
s.wsHub.PublishToUser(userID, "system_notification", notification)
return true
}
@@ -199,7 +199,7 @@ func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, m
SenderID: message.SenderID,
}
s.sseHub.PublishToUser(userID, "chat_message", map[string]interface{}{
s.wsHub.PublishToUser(userID, "chat_message", map[string]interface{}{
"detail_type": detailType,
"message": event,
})
@@ -444,7 +444,7 @@ func (s *pushServiceImpl) PushSystemMessage(ctx context.Context, userID string,
// pushSystemViaWebSocket 通过WebSocket推送系统消息
func (s *pushServiceImpl) pushSystemViaWebSocket(ctx context.Context, userID string, msgType, title, content string, data map[string]interface{}) bool {
if s.sseHub == nil || !s.sseHub.HasSubscribers(userID) {
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
return false
}
@@ -455,7 +455,7 @@ func (s *pushServiceImpl) pushSystemViaWebSocket(ctx context.Context, userID str
"data": data,
"created_at": time.Now().UnixMilli(),
}
s.sseHub.PublishToUser(userID, "system_notification", sysMsg)
s.wsHub.PublishToUser(userID, "system_notification", sysMsg)
return true
}
@@ -472,11 +472,11 @@ func (s *pushServiceImpl) PushSystemNotification(ctx context.Context, userID str
// pushSystemNotificationViaWebSocket 通过WebSocket推送系统通知
func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context, userID string, notification *model.SystemNotification) bool {
if s.sseHub == nil || !s.sseHub.HasSubscribers(userID) {
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
return false
}
sseNotification := map[string]interface{}{
wsNotification := map[string]interface{}{
"id": fmt.Sprintf("%d", notification.ID),
"type": string(notification.Type),
"title": notification.Title,
@@ -487,7 +487,7 @@ func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context
// 填充额外数据
if notification.ExtraData != nil {
extra := sseNotification["extra"].(map[string]interface{})
extra := wsNotification["extra"].(map[string]interface{})
extra["actor_id_str"] = notification.ExtraData.ActorIDStr
extra["actor_name"] = notification.ExtraData.ActorName
extra["avatar_url"] = notification.ExtraData.AvatarURL
@@ -498,7 +498,7 @@ func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context
// 设置触发用户信息
if notification.ExtraData.ActorIDStr != "" {
sseNotification["trigger_user"] = map[string]interface{}{
wsNotification["trigger_user"] = map[string]interface{}{
"id": notification.ExtraData.ActorIDStr,
"username": notification.ExtraData.ActorName,
"avatar": notification.ExtraData.AvatarURL,
@@ -506,6 +506,6 @@ func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context
}
}
s.sseHub.PublishToUser(userID, "system_notification", sseNotification)
s.wsHub.PublishToUser(userID, "system_notification", wsNotification)
return true
}