评论实时更新:SSE 订阅文章频道,发评/编辑/删除/审核通过即时刷新打开中的页面
- internal/hub:按文章 ID 的进程内发布/订阅,信号不携带内容(未审核评论不外泄) - GET /api/comments/stream?post_id=N:SSE 长连 + 25s 心跳 + X-Accel-Buffering off - 广播点:发评论、作者编辑/删除、后台审核通过、后台删除(与公开端共享同一 hub) - 前端 EventSource 静默刷新(不亮加载态、不干扰正在输入/编辑的状态) - requestLog 的 statusRecorder 补 Flush 透传——包装器没实现 Flusher 时流式端点整体不可用
This commit is contained in:
@@ -22,6 +22,7 @@ import (
|
||||
|
||||
"oneblog/internal/config"
|
||||
"oneblog/internal/httpx"
|
||||
"oneblog/internal/hub"
|
||||
"oneblog/internal/model"
|
||||
"oneblog/internal/storage"
|
||||
"oneblog/internal/store"
|
||||
@@ -32,6 +33,9 @@ type API struct {
|
||||
Store *store.Store
|
||||
Cfg *config.Config
|
||||
Sessions *Sessions
|
||||
// Hub 是评论变更广播(与公开 API 共享同一实例,main.go 装配);
|
||||
// 审核通过 / 后台删除评论时让前台打开着的页面即时刷新。
|
||||
Hub *hub.Hub
|
||||
// 文件上传的存储后端与公开域名(main.go 装配,两个 API 共享同一实例)
|
||||
Blobs storage.BlobStore
|
||||
PublicBase string
|
||||
@@ -849,6 +853,11 @@ func (a *API) adminCommentByID(w http.ResponseWriter, r *http.Request) {
|
||||
httpx.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
if in.Status == "visible" && a.Hub != nil {
|
||||
if c, err := a.Store.GetComment(id); err == nil {
|
||||
a.Hub.Broadcast(c.PostID)
|
||||
}
|
||||
}
|
||||
httpx.OK(w, map[string]any{"ok": true})
|
||||
case http.MethodDelete:
|
||||
// 后台删除同样走软删(墓碑保楼层)
|
||||
@@ -860,6 +869,11 @@ func (a *API) adminCommentByID(w http.ResponseWriter, r *http.Request) {
|
||||
httpx.ServerError(w, err)
|
||||
return
|
||||
}
|
||||
if a.Hub != nil {
|
||||
if c, err := a.Store.GetComment(id); err == nil {
|
||||
a.Hub.Broadcast(c.PostID)
|
||||
}
|
||||
}
|
||||
httpx.OK(w, map[string]any{"ok": true})
|
||||
default:
|
||||
httpx.Error(w, http.StatusMethodNotAllowed, "PUT/DELETE required")
|
||||
|
||||
Reference in New Issue
Block a user