feat:单聊页面bug修复+后台管理端好友页面bug修复+项目进度、记忆文件更新
This commit is contained in:
@@ -37,12 +37,12 @@ var upgrader = websocket.Upgrader{
|
||||
|
||||
// Handler WebSocket 连接处理器
|
||||
type Handler struct {
|
||||
hub *ws.Hub
|
||||
pubsub *ws.PubSub
|
||||
jwtCfg *config.JWTConfig
|
||||
onlineService *OnlineService
|
||||
tokenValidator TokenValidator
|
||||
offlinePusher OfflineMessagePusher
|
||||
hub *ws.Hub
|
||||
pubsub *ws.PubSub
|
||||
jwtCfg *config.JWTConfig
|
||||
onlineService *OnlineService
|
||||
tokenValidator TokenValidator
|
||||
offlinePusher OfflineMessagePusher
|
||||
}
|
||||
|
||||
// NewHandler 创建 WebSocket Handler 实例
|
||||
@@ -99,8 +99,8 @@ func (h *Handler) Upgrade(c *gin.Context) {
|
||||
|
||||
client := ws.NewClient(h.hub, conn, claims.UserID)
|
||||
client.SetOnDisconnect(func(userID int64) {
|
||||
if client.IsClosedByHub() {
|
||||
logs.Info(nil, "ws.handler.onDisconnect", "连接被 Hub 踢出(重复连接),跳过下线清理",
|
||||
if client.IsClosedByHub() && h.hub.IsOnline(userID) {
|
||||
logs.Info(nil, "ws.handler.onDisconnect", "连接被新连接替换,跳过下线清理",
|
||||
zap.Int64("user_id", userID))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -39,13 +39,44 @@ type OnlineService struct {
|
||||
}
|
||||
|
||||
// NewOnlineService 创建 OnlineService 实例
|
||||
// 启动时清理 Redis 中残留的在线状态数据,防止服务重启后出现"幽灵在线"
|
||||
func NewOnlineService(rdb *redis.Client, hub *ws.Hub, pubsub *ws.PubSub, friendGetter FriendIDsGetter) *OnlineService {
|
||||
return &OnlineService{
|
||||
svc := &OnlineService{
|
||||
rdb: rdb,
|
||||
hub: hub,
|
||||
pubsub: pubsub,
|
||||
friendGetter: friendGetter,
|
||||
}
|
||||
svc.cleanStaleOnlineData()
|
||||
return svc
|
||||
}
|
||||
|
||||
// cleanStaleOnlineData 服务启动时清理上次残留的在线状态
|
||||
// 单实例部署下,启动时不可能有合法的在线用户,直接清空即可
|
||||
func (s *OnlineService) cleanStaleOnlineData() {
|
||||
ctx := context.Background()
|
||||
funcName := "ws.online_service.cleanStaleOnlineData"
|
||||
|
||||
members, err := s.rdb.SMembers(ctx, onlineSetKey).Result()
|
||||
if err != nil {
|
||||
logs.Warn(ctx, funcName, "读取旧在线集合失败", zap.Error(err))
|
||||
return
|
||||
}
|
||||
if len(members) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
pipe := s.rdb.Pipeline()
|
||||
pipe.Del(ctx, onlineSetKey)
|
||||
for _, m := range members {
|
||||
pipe.Del(ctx, statusKeyPrefix+m)
|
||||
}
|
||||
if _, err := pipe.Exec(ctx); err != nil {
|
||||
logs.Error(ctx, funcName, "清理旧在线数据失败", zap.Error(err))
|
||||
} else {
|
||||
logs.Info(ctx, funcName, "已清理残留在线状态",
|
||||
zap.Int("stale_count", len(members)))
|
||||
}
|
||||
}
|
||||
|
||||
// UserOnline 用户上线:写入 Redis + 通知在线好友
|
||||
|
||||
Reference in New Issue
Block a user