直播后台:新增按 IP 发言管控与在线会话视图。

支持全体禁言、单 IP 禁言/解禁与同 IP 本地限频,同时在开播页展示在线会话明细并补充实时优先码率策略,兼顾实时性与并发承载。

Made-with: Cursor
This commit is contained in:
whm
2026-03-26 17:57:50 +08:00
parent 0da93fb1be
commit fe8d5a34cc
8 changed files with 535 additions and 2 deletions

View File

@@ -34,7 +34,7 @@ var allowedGifts = map[string]struct{}{
var (
danmakuClientsMu sync.Mutex
danmakuClients = make(map[*websocket.Conn]struct{})
danmakuClients = make(map[*websocket.Conn]string)
)
func writeDanmakuJSON(ws *websocket.Conn, v any) error {
@@ -71,12 +71,15 @@ func handleDanmakuWS(c *gin.Context) {
return
}
ws.SetReadLimit(4096)
clientIP := c.ClientIP()
sessionID := RegisterOnlineSession("danmaku", clientIP, fromDisplay)
danmakuClientsMu.Lock()
danmakuClients[ws] = struct{}{}
danmakuClients[ws] = clientIP
danmakuClientsMu.Unlock()
defer func() {
UnregisterOnlineSession(sessionID)
danmakuClientsMu.Lock()
delete(danmakuClients, ws)
danmakuClientsMu.Unlock()
@@ -91,6 +94,23 @@ func handleDanmakuWS(c *gin.Context) {
if mt != websocket.TextMessage {
continue
}
TouchOnlineSession(sessionID)
if IsMutedForIP(clientIP) {
_ = writeDanmakuJSON(ws, map[string]interface{}{
"type": "error",
"code": "muted",
"message": "当前已被禁言",
})
continue
}
if !AllowSendByIP(clientIP) {
_ = writeDanmakuJSON(ws, map[string]interface{}{
"type": "error",
"code": "rate_limited",
"message": "同 IP 发送过快,请稍后再试",
})
continue
}
if !canSend {
_ = writeDanmakuJSON(ws, map[string]interface{}{
"type": "error",