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)
|
content := dto.ExtractTextContentFromModel(message.Segments)
|
||||||
|
|
||||||
notification := map[string]any{
|
notification := map[string]any{
|
||||||
"id": fmt.Sprintf("%s", message.ID),
|
"id": fmt.Sprintf("%s", message.ID),
|
||||||
"type": string(message.SystemType),
|
"type": "notification",
|
||||||
"content": content,
|
"system_type": string(message.SystemType),
|
||||||
"extra": map[string]any{},
|
"content": content,
|
||||||
"created_at": message.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
"is_read": false,
|
||||||
|
"extra_data": map[string]any{},
|
||||||
|
"created_at": message.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填充额外数据
|
// 填充额外数据
|
||||||
if message.ExtraData != nil {
|
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_id"] = message.ExtraData.ActorID
|
||||||
extra["actor_name"] = message.ExtraData.ActorName
|
extra["actor_name"] = message.ExtraData.ActorName
|
||||||
extra["avatar_url"] = message.ExtraData.AvatarURL
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,19 +446,22 @@ func (s *pushServiceImpl) PushSystemMessage(ctx context.Context, userID string,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pushSystemViaWebSocket 通过WebSocket推送系统消息
|
// pushSystemViaWebSocket 通过WebSocket推送系统消息
|
||||||
|
// 使用 PublishToUserOnline 而非 PublishToUser,避免将系统消息存入断线重连历史回放
|
||||||
func (s *pushServiceImpl) pushSystemViaWebSocket(ctx context.Context, userID string, msgType, title, content string, data map[string]any) bool {
|
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) {
|
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
sysMsg := map[string]any{
|
sysMsg := map[string]any{
|
||||||
"type": msgType,
|
"type": "notification",
|
||||||
|
"system_type": msgType,
|
||||||
"title": title,
|
"title": title,
|
||||||
"content": content,
|
"content": content,
|
||||||
"data": data,
|
"is_read": false,
|
||||||
|
"extra_data": data,
|
||||||
"created_at": time.Now().Format("2006-01-02T15:04:05Z07:00"),
|
"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
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -472,24 +477,27 @@ func (s *pushServiceImpl) PushSystemNotification(ctx context.Context, userID str
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pushSystemNotificationViaWebSocket 通过WebSocket推送系统通知
|
// pushSystemNotificationViaWebSocket 通过WebSocket推送系统通知
|
||||||
|
// 使用 PublishToUserOnline 而非 PublishToUser,避免将通知存入断线重连历史回放
|
||||||
|
// 系统通知已持久化到数据库,客户端可通过 REST API 拉取,无需在重连时回放
|
||||||
func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context, userID string, notification *model.SystemNotification) bool {
|
func (s *pushServiceImpl) pushSystemNotificationViaWebSocket(ctx context.Context, userID string, notification *model.SystemNotification) bool {
|
||||||
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
|
if s.wsHub == nil || !s.wsHub.HasClients(userID) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
wsNotification := map[string]any{
|
wsNotification := map[string]any{
|
||||||
"id": fmt.Sprintf("%d", notification.ID),
|
"id": fmt.Sprintf("%d", notification.ID),
|
||||||
"type": string(notification.Type),
|
"type": "notification",
|
||||||
"title": notification.Title,
|
"system_type": string(notification.Type),
|
||||||
"content": notification.Content,
|
"title": notification.Title,
|
||||||
"is_read": notification.IsRead,
|
"content": notification.Content,
|
||||||
"extra": map[string]any{},
|
"is_read": notification.IsRead,
|
||||||
"created_at": notification.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
"extra_data": map[string]any{},
|
||||||
|
"created_at": notification.CreatedAt.Format("2006-01-02T15:04:05Z07:00"),
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填充额外数据
|
// 填充额外数据
|
||||||
if notification.ExtraData != nil {
|
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_id_str"] = notification.ExtraData.ActorIDStr
|
||||||
extra["actor_name"] = notification.ExtraData.ActorName
|
extra["actor_name"] = notification.ExtraData.ActorName
|
||||||
extra["avatar_url"] = notification.ExtraData.AvatarURL
|
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
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user