From 2b96e49d6febdceb231b48e64c13b3ac40d57c32 Mon Sep 17 00:00:00 2001 From: cheykrym Date: Tue, 21 Oct 2025 03:34:36 +0300 Subject: [PATCH] add ping socket --- yobble/Services/SocketService.swift | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/yobble/Services/SocketService.swift b/yobble/Services/SocketService.swift index 5131703..053de11 100644 --- a/yobble/Services/SocketService.swift +++ b/yobble/Services/SocketService.swift @@ -29,9 +29,12 @@ final class SocketService { connectionStateSubject.value } + private let heartbeatInterval: TimeInterval = 10 + #if canImport(SocketIO) private var manager: SocketManager? private var socket: SocketIOClient? + private var heartbeatTimer: DispatchSourceTimer? #endif private init() {} @@ -102,6 +105,7 @@ final class SocketService { setupSocket(with: token) updateConnectionState(.connecting) socket?.connect(withPayload: currentAuthPayload) + startHeartbeat() #else updateConnectionState(.disconnected) if AppConfig.DEBUG { @@ -185,12 +189,47 @@ final class SocketService { } private func disconnectInternal() { + stopHeartbeat() socket?.disconnect() manager?.disconnect() socket = nil manager = nil updateConnectionState(.disconnected) } + + private func startHeartbeat() { + guard heartbeatInterval > 0 else { return } + stopHeartbeat() + let timer = DispatchSource.makeTimerSource(queue: syncQueue) + timer.schedule(deadline: .now() + heartbeatInterval, repeating: heartbeatInterval) + timer.setEventHandler { [weak self] in + guard let self else { return } + + guard let socket = self.socket else { + self.updateConnectionState(.disconnected) + return + } + + switch socket.status { + case .connected: + self.updateConnectionState(.connected) + case .connecting: + self.updateConnectionState(.connecting) + case .disconnected, .notConnected: + self.updateConnectionState(.connecting) + socket.connect(withPayload: self.currentAuthPayload) + @unknown default: + self.updateConnectionState(.connecting) + } + } + heartbeatTimer = timer + timer.resume() + } + + private func stopHeartbeat() { + heartbeatTimer?.cancel() + heartbeatTimer = nil + } #else private func disconnectInternal() { } #endif