You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同步API中的slice与map以避免用户会话锁定

问题场景与解决方案

问题概述

我开发了一个供其他程序调用的API,核心流程如下:

  • 用户认证通过后,API返回一个专属ID,用户需使用该ID连接WebSocket
  • 发送ID时将其加入slice,确保同一凭证用户无法同时拥有两个会话
  • 用户成功连接WebSocket后,将该ID存入存储连接与ID对应关系的map中
  • 连接关闭时,从slice移除ID并删除map中对应的键值对

但存在一个异常场景:如果认证请求完成,但WebSocket连接未建立且客户端直接关闭,ID会一直留存于slice中,导致用户被锁定无法重新登录,需要解决slice与map的同步问题。

最终解决方案

我改用单个map统一存储会话信息,并在路由初始化时启动一个定时清理协程,定期移除未建立WebSocket连接的过期ID:

go func() {
    staleCheckInterval := time.Second * 10
    ticker := time.NewTicker(staleCheckInterval)
    for {
        select {
        case <-ticker.C:
            log.Println("检查过期ID")
            staleIds := []string{}
            for k, v := range handler.WsClients {
                // 如果ID生成超过10秒且未关联WebSocket连接,判定为异常状态
                if v.Ts < int(time.Now().UnixMilli())-10000 && v.WsConn == nil {
                    staleIds = append(staleIds, k)
                }
            }
            for _, id := range staleIds {
                delete(handler.WsClients, id)
                log.Println("移除ID:", id)
            }
        }
    }
}()

方案说明

  • 用单个map替代slice+map的组合,统一存储会话ID、关联的WebSocket连接、ID生成时间戳(Ts)三类信息
  • 启动定时协程,每10秒扫描一次map:
    • 筛选出"生成超过10秒且未建立WebSocket连接"的无效ID
    • 批量删除这些过期ID,避免用户因异常场景被锁定

内容的提问来源于stack exchange,提问作者Fergus Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:25:02