评论实时更新: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:
@@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { computed, nextTick, onMounted, ref } from 'vue'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { site } from '../../site'
|
||||
import { reader, loadReader, signIn, signOut } from '../../reader'
|
||||
import { readerApi } from '../../api'
|
||||
@@ -20,7 +20,19 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const api = useComments(props.postId)
|
||||
const { s, remaining, load, setSort, submit, saveEdit, remove, loadMoreReplies, startReply, startEdit, cancel } = api
|
||||
const { s, remaining, load, refresh, setSort, submit, saveEdit, remove, loadMoreReplies, startReply, startEdit, cancel } = api
|
||||
|
||||
// 新评论实时出现:订阅这篇文章的 SSE 频道,后端广播「评论变了」就静默刷新。
|
||||
// EventSource 自带断线重连;路由换文章时关旧开新。
|
||||
let stream = null
|
||||
function openStream() {
|
||||
if (stream) stream.close()
|
||||
if (!props.postId || typeof EventSource === 'undefined') return
|
||||
stream = new EventSource(`/api/comments/stream?post_id=${props.postId}`)
|
||||
stream.addEventListener('comments', () => refresh())
|
||||
}
|
||||
watch(() => props.postId, openStream, { immediate: true })
|
||||
onBeforeUnmount(() => stream && stream.close())
|
||||
|
||||
// 总开关在站点设置里。后端阶段二才会下发 comments_enabled —— 在那之前整个
|
||||
// 区块不渲染,线上访客不会看到一个请求 404 的半成品;后端一加就自动出现。
|
||||
|
||||
Reference in New Issue
Block a user