add ping pong
This commit is contained in:
parent
f886386374
commit
41adedee40
@ -39,6 +39,7 @@ final class SocketService {
|
||||
private var socket: SocketIOClient?
|
||||
private var heartbeatTimer: DispatchSourceTimer?
|
||||
private var heartbeatAckInFlight = false
|
||||
private var lastHeartbeatSentAt: Date?
|
||||
private var consecutiveHeartbeatMisses = 0
|
||||
#endif
|
||||
|
||||
@ -193,6 +194,10 @@ final class SocketService {
|
||||
self?.handleHeartbeatSuccess()
|
||||
}
|
||||
|
||||
socket.on("message") { [weak self] data, _ in
|
||||
self?.handleMessageEvent(data)
|
||||
}
|
||||
|
||||
self.manager = manager
|
||||
self.socket = socket
|
||||
}
|
||||
@ -224,6 +229,7 @@ final class SocketService {
|
||||
heartbeatTimer = nil
|
||||
heartbeatAckInFlight = false
|
||||
consecutiveHeartbeatMisses = 0
|
||||
lastHeartbeatSentAt = nil
|
||||
}
|
||||
|
||||
private func performHeartbeatCheck() {
|
||||
@ -246,43 +252,61 @@ final class SocketService {
|
||||
}
|
||||
|
||||
private func sendHeartbeat(on socket: SocketIOClient) {
|
||||
guard !heartbeatAckInFlight else { return }
|
||||
heartbeatAckInFlight = true
|
||||
|
||||
socket.emitWithAck(heartbeatEventName, ["timestamp": Date().timeIntervalSince1970])
|
||||
.timingOut(after: heartbeatTimeout) { [weak self] data in
|
||||
guard let self else { return }
|
||||
self.heartbeatAckInFlight = false
|
||||
|
||||
if self.isSuccessfulHeartbeatResponse(data) {
|
||||
self.handleHeartbeatSuccess()
|
||||
} else {
|
||||
self.handleMissedHeartbeat(for: socket)
|
||||
}
|
||||
if heartbeatAckInFlight {
|
||||
if let lastSentAt = lastHeartbeatSentAt,
|
||||
Date().timeIntervalSince(lastSentAt) >= heartbeatTimeout {
|
||||
heartbeatAckInFlight = false
|
||||
handleMissedHeartbeat(for: socket)
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
heartbeatAckInFlight = true
|
||||
lastHeartbeatSentAt = Date()
|
||||
|
||||
socket.emit(heartbeatEventName, ["data": "ping"])
|
||||
}
|
||||
|
||||
private func isSuccessfulHeartbeatResponse(_ data: [Any]) -> Bool {
|
||||
guard !data.isEmpty else { return true }
|
||||
private func handleMessageEvent(_ data: [Any]) {
|
||||
guard let payload = data.first else { return }
|
||||
|
||||
if let stringValue = data.first as? String, stringValue.uppercased() == "NO ACK" {
|
||||
return false
|
||||
let messageText: String?
|
||||
|
||||
if let dictionary = payload as? [String: Any] {
|
||||
if let nestedData = dictionary["data"] as? [String: Any],
|
||||
let nestedMessage = nestedData["message"] as? String {
|
||||
messageText = nestedMessage
|
||||
} else {
|
||||
messageText = dictionary["message"] as? String
|
||||
}
|
||||
} else if let stringValue = payload as? String {
|
||||
messageText = stringValue
|
||||
} else {
|
||||
messageText = nil
|
||||
}
|
||||
|
||||
if let ackStatus = data.first as? SocketAckStatus, ackStatus == .noAck {
|
||||
return false
|
||||
guard let message = messageText?.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() else {
|
||||
return
|
||||
}
|
||||
|
||||
return true
|
||||
if message == "pong" {
|
||||
handleHeartbeatSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
private func handleHeartbeatSuccess() {
|
||||
consecutiveHeartbeatMisses = 0
|
||||
heartbeatAckInFlight = false
|
||||
lastHeartbeatSentAt = nil
|
||||
updateConnectionState(.connected)
|
||||
}
|
||||
|
||||
private func handleMissedHeartbeat(for socket: SocketIOClient) {
|
||||
consecutiveHeartbeatMisses += 1
|
||||
heartbeatAckInFlight = false
|
||||
lastHeartbeatSentAt = nil
|
||||
updateConnectionState(.connecting)
|
||||
guard consecutiveHeartbeatMisses > maxHeartbeatMissCount else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ struct AppConfig {
|
||||
static let PROTOCOL = "https"
|
||||
static let API_SERVER = "\(PROTOCOL)://api.yobble.org"
|
||||
static let SOCKET_PATH = "/socket.io/"
|
||||
static let SOCKET_HEARTBEAT_EVENT = "ping"
|
||||
static let SOCKET_HEARTBEAT_EVENT = "client_message"
|
||||
|
||||
static let USER_AGENT = "yobble ios"
|
||||
static let APP_BUILD = "appstore" // appstore / freestore
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user