-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathSseConnectionHandler.swift
More file actions
79 lines (67 loc) · 2.25 KB
/
Copy pathSseConnectionHandler.swift
File metadata and controls
79 lines (67 loc) · 2.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//
// SseConnectionHandler.swift
// Split
//
// Created by Javier Avrudsky on 27-Oct-2022.
// Copyright © 2022 Split. All rights reserved.
//
import Foundation
import Concurrency
import Logging
public class SseConnectionHandler: @unchecked Sendable {
private let clientLock = NSLock()
private let sseClientFactory: SseClientFactory
private var curClientId: String?
private let clients = SynchronizedDictionary<String, SseClient>()
public var isConnectionOpened: Bool {
guard let id = curClientId else { return false }
return clients.value(forKey: id)?.isConnectionOpened ?? false
}
public init(sseClientFactory: SseClientFactory) {
self.sseClientFactory = sseClientFactory
}
public func connect(token: String, channels: [String], completion: @escaping SseClient.CompletionHandler) {
let sseClient = sseClientFactory.create()
addSseClient(sseClient)
sseClient.connect(token: token, channels: channels, completion: completion)
}
public func disconnect() {
Logger.d("Streaming Connection Handler - Disconnecting SSE client")
let disconnectingClientId = curClientId
clearClientId()
DispatchQueue.global().async { [weak self] in
guard let self = self else { return }
guard let clientId = disconnectingClientId else { return }
let cli = self.getSseClient(id: clientId)
cli?.disconnect()
self.removeSseClient(id: clientId)
}
}
public func destroy() {
for client in clients.takeAll().values {
client.disconnect()
}
}
private func clearClientId() {
clientLock.lock()
curClientId = nil
clientLock.unlock()
}
private func newClientId() -> String {
let id = UUID().uuidString
clientLock.lock()
curClientId = id
clientLock.unlock()
return id
}
private func addSseClient(_ newClient: SseClient) {
let id = newClientId()
clients.setValue(newClient, forKey: id)
}
private func getSseClient(id: String) -> SseClient? {
return clients.value(forKey: id)
}
private func removeSseClient(id: String) {
clients.removeValue(forKey: id)
}
}