群聊生命周期事件对被动成员实时不可见——前端兜底同步(真正的根因在后端,无法单靠前端代码彻底解决)
读im_be的server/im_group_events.go确认:群聊创建/加人/踢人/解散/转让群主等全部事件都走 publishIMGroupRealtimeEvent,这个函数只会广播给"当前已订阅该群topic的会话"——对比P2P场景专门 有一条deliverIMConversationSystemMessageToP2PSessions,会无视订阅状态强制投递给双方的session, 群聊从未做过同等实现。实机验证:一个全新创建、成员从未打开过的群,即使对方账号完全在线、页面就 停留在/messages上,群条目和未读角标都不会出现,等多久都不会自愈,必须手动刷新页面。 由于这个topic客户端本来就不知道存在,没有任何东西可以"响应",前端无法真正修复,只能缓解:复用 subscribeMeTopic()/onReauthenticated()已经在用的withLaterSub()增量语义,改用getMeta()(不像 subscribe()那样在_attached为true时直接短路)定时(30秒)+ 切回标签页时主动拉一次"me"话题的最新 订阅列表。 实机验证:创建一个全新群、只邀请一个从未见过这个群的被动成员,在其页面保持被动、不做任何操作/ 刷新的情况下——模拟切换标签页触发的focus/visibilitychange事件后约十几秒内,群条目正确出现在 列表顶部;另一次未受干预的测试中,纯靠30秒定时器本身也确认能自愈。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
d1f3aea26e
commit
ab3843dbdb
@@ -5,7 +5,7 @@ import { Navigate, Outlet } from 'react-router-dom';
|
||||
import { Toast } from '@/app/Toast';
|
||||
import { restoreSession } from '@/lib/tinode/connection';
|
||||
import { isTenantMismatch } from '@/lib/tinode/errors';
|
||||
import { subscribeMeTopic } from '@/lib/tinode/topics';
|
||||
import { startMeReconciliation, subscribeMeTopic } from '@/lib/tinode/topics';
|
||||
import { useSessionStore } from '@/stores/session';
|
||||
|
||||
/** No connect-timeout exists anywhere in the SDK (its WS promise only settles on the underlying
|
||||
@@ -81,6 +81,15 @@ export function RequireAuth() {
|
||||
subscribeMeTopic().catch(() => setContactsError('会话列表加载失败,请刷新页面重试'));
|
||||
}, [myUserId]);
|
||||
|
||||
// Separate from the one-time subscribeMeTopic effect above on purpose: this one has real
|
||||
// start/stop semantics (a timer + listeners, not a non-idempotent WS packet) and needs to
|
||||
// restart cleanly across StrictMode's mount->cleanup->remount, not be guarded against it. See
|
||||
// startMeReconciliation's own comment for what backend gap this is mitigating.
|
||||
useEffect(() => {
|
||||
if (!myUserId) return undefined;
|
||||
return startMeReconciliation();
|
||||
}, [myUserId]);
|
||||
|
||||
if (!tenant) return <Navigate to="/tenant" replace />;
|
||||
if (myUserId) {
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user