refactor(push): normalize notification payload and avoid reconnection replay
- Change type field to always be "notification" and add system_type field - Rename "extra" and "data" fields to "extra_data" for consistency - Add "is_read" field to notification payload - Use PublishToUserOnline instead of PublishToUser to prevent system messages from being stored in reconnection history replay - System notifications are already persisted to database, clients can fetch via REST API on reconnect
This commit is contained in:
@@ -149,16 +149,18 @@ func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, m
|
||||
content := dto.ExtractTextContentFromModel(message.Segments)
|
||||
|
||||
notification := map[string]any{
|
||||
"id": fmt.Sprintf("%s", message.ID),
|
||||
"type": string(message.SystemType),
|
||||
"content": content,
|
||||
"extra": map[string]any{},
|
||||
"created_at": message.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
"id": fmt.Sprintf("%s", message.ID),
|
||||
"type": "notification",
|
||||
"system_type": string(message.SystemType),
|
||||
"content": content,
|
||||
"is_read": false,
|
||||
"extra_data": map[string]any{},
|
||||
"created_at": message.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
}
|
||||
|
||||
// 填充额外数据
|
||||
if message.ExtraData != nil {
|
||||
extra := notification["extra"].(map[string]any)
|
||||
extra := notification["extra_data"].(map[string]any)
|
||||
extra["actor_id"] = message.ExtraData.ActorID
|
||||
extra["actor_name"] = message.ExtraData.ActorName
|
||||
extra["avatar_url"] = message.ExtraData.AvatarURL
|
||||
@@ -174,7 +176,7 @@ func (s *pushServiceImpl) pushViaWebSocket(ctx context.Context, userID string, m
|
||||
}
|
||||
}
|
||||
}
|
||||
s.wsHub.PublishToUser(userID, "system_notification", notification)
|
||||
s.wsHub.PublishToUserOnline(userID, "system_notification", notification)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -444,19 +446,22 @@ func (s *pushServiceImpl) PushSystemMessage(ctx context.Context, userID string,
|
||||
}
|
||||
|
||||
// pushSystemViaWebSocket 通过WebSocket推送系统消息
|
||||
// 使用 PublishToUserOnline 而非 PublishToUser,避免将系统消息存入断线重连历史回放
|
||||
func (s *pushServiceImpl) pushSystemViaWebSocket(ctx context.Context, userID string, msgType, title, content string, data map[string]any) bool {
|
||||
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
|
||||
return false
|
||||
}
|
||||
|
||||
sysMsg := map[string]any{
|
||||
"type": msgType,
|
||||
"type": "notification",
|
||||
"system_type": msgType,
|
||||
"title": title,
|
||||
"content": content,
|
||||
"data": data,
|
||||
"is_read": false,
|
||||
"extra_data": data,
|
||||
"created_at": time.Now().Format("2006-01-02T15:04:05Z07:00"),
|
||||
}
|
||||
s.wsHub.PublishToUser(userID, "system_notification", sysMsg)
|
||||
s.wsHub.PublishToUserOnline(userID, "system_notification", sysMsg)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -472,24 +477,27 @@ func (s *pushServiceImpl) PushSystemNotification(ctx context.Context, userID str
|
||||
}
|
||||
|
||||
// pushSystemNotificationViaWebSocket 通过WebSocket推送系统通知
|
||||
// 使用 PublishToUserOnline 而非 PublishToUser,避免将通知存入断线重连历史回放
|
||||
// 系统通知已持久化到数据库,客户端可通过 REST API 拉取,无需在重连时回放
|
||||
func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context, userID string, notification *model.SystemNotification) bool {
|
||||
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
|
||||
return false
|
||||
}
|
||||
|
||||
wsNotification := map[string]any{
|
||||
"id": fmt.Sprintf("%d", notification.ID),
|
||||
"type": string(notification.Type),
|
||||
"title": notification.Title,
|
||||
"content": notification.Content,
|
||||
"is_read": notification.IsRead,
|
||||
"extra": map[string]any{},
|
||||
"created_at": notification.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
"id": fmt.Sprintf("%d", notification.ID),
|
||||
"type": "notification",
|
||||
"system_type": string(notification.Type),
|
||||
"title": notification.Title,
|
||||
"content": notification.Content,
|
||||
"is_read": notification.IsRead,
|
||||
"extra_data": map[string]any{},
|
||||
"created_at": notification.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||
}
|
||||
|
||||
// 填充额外数据
|
||||
if notification.ExtraData != nil {
|
||||
extra := wsNotification["extra"].(map[string]any)
|
||||
extra := wsNotification["extra_data"].(map[string]any)
|
||||
extra["actor_id_str"] = notification.ExtraData.ActorIDStr
|
||||
extra["actor_name"] = notification.ExtraData.ActorName
|
||||
extra["avatar_url"] = notification.ExtraData.AvatarURL
|
||||
@@ -508,6 +516,6 @@ func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context
|
||||
}
|
||||
}
|
||||
|
||||
s.wsHub.PublishToUser(userID, "system_notification", wsNotification)
|
||||
s.wsHub.PublishToUserOnline(userID, "system_notification", wsNotification)
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user