ralph/collaboration-and-character-variables #9
|
|
@ -691,7 +691,7 @@ function FlowchartEditorInner({ projectId, projectName, userId, userDisplayName,
|
|||
useEffect(() => {
|
||||
const handleVisibilityChange = () => {
|
||||
if (!document.hidden) {
|
||||
realtimeRef.current?.notifyActivity()
|
||||
realtimeRef.current?.notifyVisibilityResumed()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const RECONNECT_BASE_DELAY_MS = 1000
|
|||
const RECONNECT_MAX_DELAY_MS = 30_000
|
||||
const INACTIVITY_TIMEOUT_MS = 5 * 60_000 // 5 minutes of inactivity before pausing
|
||||
const CONNECTION_TIMEOUT_MS = 15_000 // 15s timeout for initial connection
|
||||
const STALE_THRESHOLD_MS = 60_000 // 60s of inactivity = force fresh reconnect on return
|
||||
const STALE_THRESHOLD_MS = 3 * 60_000 // 3 minutes hidden before forcing fresh reconnect
|
||||
|
||||
export class RealtimeConnection {
|
||||
private channel: RealtimeChannel | null = null
|
||||
|
|
@ -262,21 +262,31 @@ export class RealtimeConnection {
|
|||
/**
|
||||
* Notify that user activity has occurred, resetting the inactivity timer.
|
||||
* If the connection was paused due to inactivity, it will resume.
|
||||
* If the connection was idle for a significant period, force a fresh reconnect
|
||||
* to ensure the WebSocket isn't stale.
|
||||
*/
|
||||
notifyActivity(): void {
|
||||
if (this.isDestroyed) return
|
||||
this.lastActivityTime = Date.now()
|
||||
this.resetInactivityTimer()
|
||||
|
||||
if (this.isPaused) {
|
||||
this.resume()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the tab becomes visible again. If the tab was hidden for a
|
||||
* significant period, force a fresh reconnect to handle stale WebSockets.
|
||||
*/
|
||||
notifyVisibilityResumed(): void {
|
||||
if (this.isDestroyed) return
|
||||
const now = Date.now()
|
||||
const idleDuration = now - this.lastActivityTime
|
||||
const hiddenDuration = now - this.lastActivityTime
|
||||
this.lastActivityTime = now
|
||||
this.resetInactivityTimer()
|
||||
|
||||
if (this.isPaused) {
|
||||
this.resume()
|
||||
} else if (idleDuration > STALE_THRESHOLD_MS && this.channel) {
|
||||
// Connection may appear alive but WebSocket could be stale after idle.
|
||||
// Force a fresh reconnect to ensure broadcasts actually work.
|
||||
} else if (hiddenDuration > STALE_THRESHOLD_MS && this.channel) {
|
||||
this.forceReconnect()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue