fix vc desync
This commit is contained in:
parent
e00bfdce39
commit
6a14104143
4 changed files with 314 additions and 82 deletions
|
|
@ -4206,6 +4206,55 @@ function handleChatInputKey(event) {
|
|||
let dmMessagePollInterval = null;
|
||||
let appWebSocket = null;
|
||||
let dmMessageLoadTimeout = null;
|
||||
let appWsPingTimer = null;
|
||||
let callStatesResyncTimer = null;
|
||||
|
||||
//Keepalive app-WS: tekstowy "ping" co 20 s. Serwer zamyka połączenie po 75 s
|
||||
//bezczynności (AppWsIdleTimeout) - bez tego half-open TCP po zabiciu aplikacji /
|
||||
//zmianie sieci wisiał na serwerze godzinami, cleanup ActiveCalls nie biegł i
|
||||
//wskaźniki rozmów pokazywały uczestników, którzy dawno wyszli. Ping utrzymuje
|
||||
//też mapping NAT przy danych komórkowych, więc eventy (call_update!) nie giną.
|
||||
function startAppWsPing() {
|
||||
if (appWsPingTimer) clearInterval(appWsPingTimer);
|
||||
appWsPingTimer = setInterval(() => {
|
||||
if (appWebSocket && appWebSocket.readyState === WebSocket.OPEN) {
|
||||
try { appWebSocket.send("ping"); } catch (e) {}
|
||||
}
|
||||
}, 20000);
|
||||
}
|
||||
|
||||
function stopAppWsPing() {
|
||||
if (appWsPingTimer) { clearInterval(appWsPingTimer); appWsPingTimer = null; }
|
||||
}
|
||||
|
||||
//Pełna resynchronizacja wskaźników rozmów: zgubiony podczas przerwy w app-WS
|
||||
//call_update NIGDY nie jest odtwarzany przez serwer, a seedCallStateFromList
|
||||
//tylko dodaje wpisy - bez tego wskaźniki "znikały dopiero po ręcznym odświeżeniu".
|
||||
//Dla każdego pokoju znanego jako aktywny (+ otwartego) pyta room/voice/state
|
||||
//i koryguje mapę oraz UI. Uruchamiane: po (re)otwarciu WS, co 30 s, przy powrocie
|
||||
//karty/aplikacji na wierzch.
|
||||
async function resyncAllCallStates() {
|
||||
if (!window.id || typeof fetchEncrypted !== "function" || typeof ensureActiveCallsMap !== "function") return;
|
||||
let map = ensureActiveCallsMap();
|
||||
let keys = Object.keys(map);
|
||||
let currentKey = window.currentDmId ? sanitizeId(window.currentDmId) : null;
|
||||
if (currentKey && !keys.includes(currentKey)) keys.push(currentKey);
|
||||
if (keys.length === 0) return;
|
||||
|
||||
for (let key of keys) {
|
||||
let roomType = window.currentDmId === key && window.currentRoomType ? window.currentRoomType
|
||||
: (String(key).includes("_") ? "dms" : "groups");
|
||||
try {
|
||||
let res = await fetchEncrypted("room/voice/state", JSON.stringify({ string1: roomType, string2: key }));
|
||||
if (!res || !res.startsWith("[")) continue;
|
||||
let participants = JSON.parse(res).map(u => String(u).split(";")[0]);
|
||||
if (participants.length > 0) map[key] = participants;
|
||||
else delete map[key];
|
||||
} catch (e) {}
|
||||
}
|
||||
//Po serii poprawek pełne przerysowanie wskaźników (listy + top-bary + details)
|
||||
if (typeof updateVoicePresenceUI === "function") updateVoicePresenceUI();
|
||||
}
|
||||
|
||||
function setupWebSocket() {
|
||||
if (appWebSocket && (appWebSocket.readyState === WebSocket.OPEN || appWebSocket.readyState === WebSocket.CONNECTING)) return;
|
||||
|
|
@ -4228,6 +4277,17 @@ function setupWebSocket() {
|
|||
} finally {
|
||||
release();
|
||||
}
|
||||
|
||||
startAppWsPing();
|
||||
//Po każdym (re)połączeniu odtwarzamy stan wskaźników - eventy call_update
|
||||
//z czasu rozłączenia są bezpowrotnie stracone
|
||||
resyncAllCallStates();
|
||||
if (!callStatesResyncTimer) {
|
||||
callStatesResyncTimer = setInterval(() => {
|
||||
if (document.visibilityState !== "visible") return;
|
||||
resyncAllCallStates();
|
||||
}, 30000);
|
||||
}
|
||||
};
|
||||
|
||||
appWebSocket.onmessage = (event) => {
|
||||
|
|
@ -4273,10 +4333,22 @@ function setupWebSocket() {
|
|||
};
|
||||
|
||||
appWebSocket.onclose = () => {
|
||||
stopAppWsPing();
|
||||
setTimeout(setupWebSocket, 5000);
|
||||
};
|
||||
}
|
||||
|
||||
//Powrót karty/aplikacji na wierzch: mobilne WebView potrafią trzymać martwy
|
||||
//socket odkryty bardzo długo (brak ramek = brak detekcji). Wymuszamy próbę
|
||||
//połączenia i od razu resynchronizujemy wskaźniki rozmów.
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (document.visibilityState !== "visible") return;
|
||||
if (appWebSocket && appWebSocket.readyState !== WebSocket.OPEN && appWebSocket.readyState !== WebSocket.CONNECTING) {
|
||||
setupWebSocket();
|
||||
}
|
||||
resyncAllCallStates();
|
||||
});
|
||||
|
||||
let currentContextMenuMsgId = null;
|
||||
let touchContextMenuFired = false;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue