Уведомления в фоне, оптимизация FPS чата, release notes, read receipts паритет с Android

This commit is contained in:
2026-03-18 20:10:20 +05:00
parent 1f442e1298
commit 422b20702e
42 changed files with 2459 additions and 656 deletions

View File

@@ -105,14 +105,39 @@ final class ProtocolManager: @unchecked Sendable {
}
/// Verify connection health after returning from background.
/// Always force reconnect after background, the socket is likely dead
/// and a 2s ping timeout just delays the inevitable.
/// Fast path: if already authenticated, send a WebSocket ping first (< 100ms).
/// If pong arrives, connection is alive no reconnect needed.
/// If ping fails or times out (500ms), force full reconnect.
func reconnectIfNeeded() {
guard savedPublicKey != nil, savedPrivateHash != nil else { return }
// Don't interrupt active handshake
if connectionState == .handshaking { return }
// Fast path: if authenticated, try ping first before tearing down.
if connectionState == .authenticated, client.isConnected {
Self.logger.info("Foreground — ping check")
client.sendPing { [weak self] error in
guard let self else { return }
if error == nil {
// Pong received connection alive, send heartbeat to keep it fresh.
Self.logger.info("Foreground ping OK — connection alive")
self.client.sendText("heartbeat")
return
}
// Ping failed connection dead, force reconnect.
Self.logger.info("Foreground ping failed — force reconnecting")
self.handshakeComplete = false
self.heartbeatTask?.cancel()
Task { @MainActor in
self.connectionState = .connecting
}
self.client.forceReconnect()
}
return
}
// Not authenticated force reconnect immediately.
Self.logger.info("Foreground reconnect — force reconnecting")
handshakeComplete = false
heartbeatTask?.cancel()