Replace websocket flow with SSE support in backend.
Update handlers, services, router, and data conversion logic to support server-sent events and related message pipeline changes. Made-with: Cursor
This commit is contained in:
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
"carrot_bbs/internal/cache"
|
||||
"carrot_bbs/internal/model"
|
||||
"carrot_bbs/internal/pkg/sse"
|
||||
"carrot_bbs/internal/pkg/utils"
|
||||
"carrot_bbs/internal/pkg/websocket"
|
||||
"carrot_bbs/internal/repository"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
|
||||
// 缓存TTL常量
|
||||
const (
|
||||
GroupMembersTTL = 120 * time.Second // 群组成员缓存120秒
|
||||
GroupMembersTTL = 120 * time.Second // 群组成员缓存120秒
|
||||
GroupMembersNullTTL = 5 * time.Second
|
||||
GroupCacheJitter = 0.1
|
||||
)
|
||||
@@ -99,12 +99,12 @@ type groupService struct {
|
||||
messageRepo *repository.MessageRepository
|
||||
requestRepo repository.GroupJoinRequestRepository
|
||||
notifyRepo *repository.SystemNotificationRepository
|
||||
wsManager *websocket.WebSocketManager
|
||||
sseHub *sse.Hub
|
||||
cache cache.Cache
|
||||
}
|
||||
|
||||
// NewGroupService 创建群组服务
|
||||
func NewGroupService(db *gorm.DB, groupRepo repository.GroupRepository, userRepo *repository.UserRepository, messageRepo *repository.MessageRepository, wsManager *websocket.WebSocketManager) GroupService {
|
||||
func NewGroupService(db *gorm.DB, groupRepo repository.GroupRepository, userRepo *repository.UserRepository, messageRepo *repository.MessageRepository, sseHub *sse.Hub) GroupService {
|
||||
return &groupService{
|
||||
db: db,
|
||||
groupRepo: groupRepo,
|
||||
@@ -112,11 +112,39 @@ func NewGroupService(db *gorm.DB, groupRepo repository.GroupRepository, userRepo
|
||||
messageRepo: messageRepo,
|
||||
requestRepo: repository.NewGroupJoinRequestRepository(db),
|
||||
notifyRepo: repository.NewSystemNotificationRepository(db),
|
||||
wsManager: wsManager,
|
||||
sseHub: sseHub,
|
||||
cache: cache.GetCache(),
|
||||
}
|
||||
}
|
||||
|
||||
type groupNoticeData struct {
|
||||
UserID string `json:"user_id,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
OperatorID string `json:"operator_id,omitempty"`
|
||||
}
|
||||
|
||||
type groupNoticeMessage struct {
|
||||
NoticeType string `json:"notice_type"`
|
||||
GroupID string `json:"group_id"`
|
||||
Data groupNoticeData `json:"data"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
MessageID string `json:"message_id,omitempty"`
|
||||
Seq int64 `json:"seq,omitempty"`
|
||||
}
|
||||
|
||||
func (s *groupService) publishGroupNotice(groupID string, notice groupNoticeMessage) {
|
||||
members, _, err := s.groupRepo.GetMembers(groupID, 1, 1000)
|
||||
if err != nil {
|
||||
log.Printf("[groupService] 获取群成员失败: groupID=%s, err=%v", groupID, err)
|
||||
return
|
||||
}
|
||||
if s.sseHub != nil {
|
||||
for _, m := range members {
|
||||
s.sseHub.PublishToUser(m.UserID, "group_notice", notice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 群组管理 ====================
|
||||
|
||||
// CreateGroup 创建群组
|
||||
@@ -422,14 +450,10 @@ func (s *groupService) broadcastMemberJoinNotice(groupID string, targetUserID st
|
||||
}
|
||||
}
|
||||
|
||||
if s.wsManager == nil {
|
||||
return
|
||||
}
|
||||
|
||||
noticeMsg := websocket.GroupNoticeMessage{
|
||||
noticeMsg := groupNoticeMessage{
|
||||
NoticeType: "member_join",
|
||||
GroupID: groupID,
|
||||
Data: websocket.GroupNoticeData{
|
||||
Data: groupNoticeData{
|
||||
UserID: targetUserID,
|
||||
Username: targetUserName,
|
||||
OperatorID: operatorID,
|
||||
@@ -441,17 +465,7 @@ func (s *groupService) broadcastMemberJoinNotice(groupID string, targetUserID st
|
||||
noticeMsg.Seq = savedMessage.Seq
|
||||
}
|
||||
|
||||
wsMsg := websocket.CreateWSMessage(websocket.MessageTypeGroupNotice, noticeMsg)
|
||||
members, _, err := s.groupRepo.GetMembers(groupID, 1, 1000)
|
||||
if err != nil {
|
||||
log.Printf("[broadcastMemberJoinNotice] 获取群成员失败: groupID=%s, err=%v", groupID, err)
|
||||
return
|
||||
}
|
||||
for _, m := range members {
|
||||
if s.wsManager.IsUserOnline(m.UserID) {
|
||||
s.wsManager.SendToUser(m.UserID, wsMsg)
|
||||
}
|
||||
}
|
||||
s.publishGroupNotice(groupID, noticeMsg)
|
||||
}
|
||||
|
||||
func (s *groupService) addMemberToGroupAndConversation(group *model.Group, userID string, operatorID string) error {
|
||||
@@ -1282,46 +1296,20 @@ func (s *groupService) MuteMember(userID string, groupID string, targetUserID st
|
||||
}
|
||||
}
|
||||
|
||||
// 发送WebSocket通知给群成员
|
||||
if s.wsManager != nil {
|
||||
log.Printf("[MuteMember] 准备发送禁言通知: groupID=%s, targetUserID=%s, noticeType=%s, operatorID=%s", groupID, targetUserID, noticeType, userID)
|
||||
|
||||
// 构建通知消息,包含保存的消息信息
|
||||
noticeMsg := websocket.GroupNoticeMessage{
|
||||
NoticeType: noticeType,
|
||||
GroupID: groupID,
|
||||
Data: websocket.GroupNoticeData{
|
||||
UserID: targetUserID,
|
||||
OperatorID: userID,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
|
||||
// 如果消息已保存,添加消息ID和seq
|
||||
if savedMessage != nil {
|
||||
noticeMsg.MessageID = savedMessage.ID
|
||||
noticeMsg.Seq = savedMessage.Seq
|
||||
}
|
||||
|
||||
wsMsg := websocket.CreateWSMessage(websocket.MessageTypeGroupNotice, noticeMsg)
|
||||
log.Printf("[MuteMember] 创建的WebSocket消息: Type=%s, Data=%+v", wsMsg.Type, wsMsg.Data)
|
||||
|
||||
// 获取所有群成员并发送通知
|
||||
members, _, err := s.groupRepo.GetMembers(groupID, 1, 1000)
|
||||
if err == nil {
|
||||
log.Printf("[MuteMember] 获取到群成员数量: %d", len(members))
|
||||
for _, m := range members {
|
||||
isOnline := s.wsManager.IsUserOnline(m.UserID)
|
||||
log.Printf("[MuteMember] 成员 %s 在线状态: %v", m.UserID, isOnline)
|
||||
if isOnline {
|
||||
s.wsManager.SendToUser(m.UserID, wsMsg)
|
||||
log.Printf("[MuteMember] 已发送通知给成员: %s", m.UserID)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Printf("[MuteMember] 获取群成员失败: %v", err)
|
||||
}
|
||||
noticeMsg := groupNoticeMessage{
|
||||
NoticeType: noticeType,
|
||||
GroupID: groupID,
|
||||
Data: groupNoticeData{
|
||||
UserID: targetUserID,
|
||||
OperatorID: userID,
|
||||
},
|
||||
Timestamp: time.Now().UnixMilli(),
|
||||
}
|
||||
if savedMessage != nil {
|
||||
noticeMsg.MessageID = savedMessage.ID
|
||||
noticeMsg.Seq = savedMessage.Seq
|
||||
}
|
||||
s.publishGroupNotice(groupID, noticeMsg)
|
||||
|
||||
// 失效群组成员缓存
|
||||
cache.InvalidateGroupMembers(s.cache, groupID)
|
||||
|
||||
Reference in New Issue
Block a user