perf: SSE 实时事件驱动未读数量刷新,轮询间隔从 30s 降至 5min

This commit is contained in:
yml2213
2026-06-29 17:26:54 +08:00
parent 56e61428b0
commit 8498884cb4
4 changed files with 18 additions and 3 deletions
@@ -4,6 +4,9 @@ import type { RouteLocationNormalizedLoaded } from 'vue-router'
import { fetchUnreadChatCount } from '@/features/chats/api/chats' import { fetchUnreadChatCount } from '@/features/chats/api/chats'
import { useSessionStore } from '@/stores/session' import { useSessionStore } from '@/stores/session'
const pollingInterval = 300_000
const unreadChangedEvent = 'chat-unread-changed'
export function useChatUnreadCount(route: RouteLocationNormalizedLoaded) { export function useChatUnreadCount(route: RouteLocationNormalizedLoaded) {
const session = useSessionStore() const session = useSessionStore()
const unreadCount = ref(0) const unreadCount = ref(0)
@@ -32,14 +35,19 @@ export function useChatUnreadCount(route: RouteLocationNormalizedLoaded) {
unreadCount.value = count unreadCount.value = count
} }
} catch { } catch {
// 底部导航不弹错误提示,保持上一次未读数即可。 // 不弹错误提示,保持上一次未读数即可。
} }
} }
function onUnreadChanged() {
void loadUnreadCount()
}
function startPolling() { function startPolling() {
stopPolling() stopPolling()
void loadUnreadCount() void loadUnreadCount()
timer = window.setInterval(loadUnreadCount, 30_000) timer = window.setInterval(loadUnreadCount, pollingInterval)
window.addEventListener(unreadChangedEvent, onUnreadChanged)
} }
onMounted(() => { onMounted(() => {
@@ -48,7 +56,10 @@ export function useChatUnreadCount(route: RouteLocationNormalizedLoaded) {
} }
}) })
onBeforeUnmount(stopPolling) onBeforeUnmount(() => {
stopPolling()
window.removeEventListener(unreadChangedEvent, onUnreadChanged)
})
watch( watch(
() => session.isLoggedIn, () => session.isLoggedIn,
@@ -58,6 +69,7 @@ export function useChatUnreadCount(route: RouteLocationNormalizedLoaded) {
return return
} }
stopPolling() stopPolling()
window.removeEventListener(unreadChangedEvent, onUnreadChanged)
unreadCount.value = 0 unreadCount.value = 0
} }
) )
@@ -48,6 +48,7 @@ const desktopNotification = useDesktopNotification('user')
function handleSSEEvent(event: ChatEvent) { function handleSSEEvent(event: ChatEvent) {
if (event.type === 'new_message') { if (event.type === 'new_message') {
window.dispatchEvent(new Event('chat-unread-changed'))
const msg = event.message const msg = event.message
if (msg) { if (msg) {
const isSelf = msg.sender_type === 'user' && msg.sender_id === currentUserId const isSelf = msg.sender_type === 'user' && msg.sender_id === currentUserId
@@ -81,6 +81,7 @@ async function loadChats(isRefresh = false, showLoading = true) {
function handleSSEEvent(event: ChatEvent) { function handleSSEEvent(event: ChatEvent) {
if (event.type === 'new_message' || event.type === 'conversation_updated') { if (event.type === 'new_message' || event.type === 'conversation_updated') {
loadChats(true, false) loadChats(true, false)
window.dispatchEvent(new Event('chat-unread-changed'))
} }
if (event.type === 'new_message' && event.message) { if (event.type === 'new_message' && event.message) {
const isSelf = event.message.sender_type === 'user' && event.message.sender_id === currentUserId const isSelf = event.message.sender_type === 'user' && event.message.sender_id === currentUserId
@@ -44,6 +44,7 @@ const desktopNotification = useDesktopNotification('user')
function handleSSEEvent(event: ChatEvent) { function handleSSEEvent(event: ChatEvent) {
if (event.type === 'new_message') { if (event.type === 'new_message') {
window.dispatchEvent(new Event('chat-unread-changed'))
const msg = event.message const msg = event.message
if (msg) { if (msg) {
const isSelf = msg.sender_type === 'user' && msg.sender_id === currentUserId const isSelf = msg.sender_type === 'user' && msg.sender_id === currentUserId