Skip to content

Commit 94c7474

Browse files
authored
Fix ParseLiveQuery closing all connections from server request (#176)
* Fix ParseLiveQuery closing all connections from server request * Switch to closedSocket * Update .codecov.yml
1 parent a9606df commit 94c7474

File tree

7 files changed

+61
-12
lines changed

7 files changed

+61
-12
lines changed

.codecov.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ coverage:
44
status:
55
patch:
66
default:
7-
target: 0
7+
target: 45
88
changes: false
99
project:
1010
default:
11-
target: 80
11+
target: 81
1212
comment:
1313
require_changes: true

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.8.4...main)
55
* _Contributing to this repo? Add info about your change here to be included in the next release_
66

7+
__Fixes__
8+
- Fixed a bug in LiveQuery when a close frame is sent from the server that resulted in closing
9+
all running websocket tasks instead of the particular task the request was intended for. The fix
10+
includes a new delegate method named `closedSocket()` which provides the close code
11+
and reason the server closed the connection ([#176](https://github.com/parse-community/Parse-Swift/pull/176)), thanks to [Corey Baker](https://github.com/cbaker6).
12+
713
### 1.8.4
814
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.8.3...1.8.4)
915

Sources/ParseSwift/LiveQuery/LiveQuerySocket.swift

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,16 +128,18 @@ extension LiveQuerySocket: URLSessionWebSocketDelegate {
128128
func urlSession(_ session: URLSession,
129129
webSocketTask: URLSessionWebSocketTask,
130130
didOpenWithProtocol protocol: String?) {
131-
delegates[webSocketTask]?.status(.open)
131+
delegates[webSocketTask]?.status(.open,
132+
closeCode: nil,
133+
reason: nil)
132134
}
133135

134136
func urlSession(_ session: URLSession,
135137
webSocketTask: URLSessionWebSocketTask,
136138
didCloseWith closeCode: URLSessionWebSocketTask.CloseCode,
137139
reason: Data?) {
138-
self.delegates.forEach { (_, value) -> Void in
139-
value.status(.closed)
140-
}
140+
delegates[webSocketTask]?.status(.closed,
141+
closeCode: closeCode,
142+
reason: reason)
141143
}
142144

143145
func urlSession(_ session: URLSession,
@@ -151,11 +153,12 @@ extension LiveQuerySocket: URLSessionWebSocketDelegate {
151153
}
152154

153155
#if !os(watchOS)
154-
func urlSession(_ session: URLSession, task: URLSessionTask, didFinishCollecting metrics: URLSessionTaskMetrics) {
155-
if let socketTask = task as? URLSessionWebSocketTask {
156-
if let transactionMetrics = metrics.transactionMetrics.last {
156+
func urlSession(_ session: URLSession,
157+
task: URLSessionTask,
158+
didFinishCollecting metrics: URLSessionTaskMetrics) {
159+
if let socketTask = task as? URLSessionWebSocketTask,
160+
let transactionMetrics = metrics.transactionMetrics.last {
157161
delegates[socketTask]?.received(transactionMetrics)
158-
}
159162
}
160163
}
161164
#endif

Sources/ParseSwift/LiveQuery/ParseLiveQuery.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,13 +307,18 @@ extension ParseLiveQuery {
307307
@available(macOS 10.15, iOS 13.0, macCatalyst 13.0, watchOS 6.0, tvOS 13.0, *)
308308
extension ParseLiveQuery: LiveQuerySocketDelegate {
309309

310-
func status(_ status: LiveQuerySocket.Status) {
310+
func status(_ status: LiveQuerySocket.Status,
311+
closeCode: URLSessionWebSocketTask.CloseCode? = nil,
312+
reason: Data? = nil) {
311313
switch status {
312314

313315
case .open:
314316
self.isSocketEstablished = true
315317
self.open(isUserWantsToConnect: false) { _ in }
316318
case .closed:
319+
self.notificationQueue.async {
320+
self.receiveDelegate?.closedSocket(closeCode, reason: reason)
321+
}
317322
self.isSocketEstablished = false
318323
if !self.isDisconnectedByUser {
319324
//Try to reconnect

Sources/ParseSwift/LiveQuery/Protocols/LiveQuerySocketDelegate.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ import FoundationNetworking
1313

1414
@available(macOS 10.15, iOS 13.0, macCatalyst 13.0, watchOS 6.0, tvOS 13.0, *)
1515
protocol LiveQuerySocketDelegate: AnyObject {
16-
func status(_ status: LiveQuerySocket.Status)
16+
func status(_ status: LiveQuerySocket.Status,
17+
closeCode: URLSessionWebSocketTask.CloseCode?,
18+
reason: Data?)
1719
func close(useDedicatedQueue: Bool)
1820
func receivedError(_ error: ParseError)
1921
func receivedUnsupported(_ data: Data?, socketMessage: URLSessionWebSocketTask.Message?)

Sources/ParseSwift/LiveQuery/Protocols/ParseLiveQueryDelegate.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ public protocol ParseLiveQueryDelegate: AnyObject {
5757
*/
5858
func received(_ metrics: URLSessionTaskTransactionMetrics)
5959
#endif
60+
61+
/**
62+
Receive notifications when the ParseLiveQuery closes a task/connection.
63+
- parameter code: The close code provided by the server.
64+
- parameter reason: The close reason provided by the server.
65+
If the close frame didn’t include a reason, this value is nil.
66+
*/
67+
func closedSocket(_ code: URLSessionWebSocketTask.CloseCode?, reason: Data?)
6068
}
6169

6270
@available(macOS 10.15, iOS 13.0, macCatalyst 13.0, watchOS 6.0, tvOS 13.0, *)
@@ -69,5 +77,6 @@ extension ParseLiveQueryDelegate {
6977
func received(_ error: ParseError) { }
7078
func receivedUnsupported(_ data: Data?, socketMessage: URLSessionWebSocketTask.Message?) { }
7179
func received(_ metrics: URLSessionTaskTransactionMetrics) { }
80+
func closedSocket(_ code: URLSessionWebSocketTask.CloseCode?, reason: Data?) { }
7281
}
7382
#endif

Tests/ParseSwiftTests/ParseLiveQueryTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,15 @@ class ParseLiveQueryTests: XCTestCase {
3434

3535
class TestDelegate: ParseLiveQueryDelegate {
3636
var error: ParseError?
37+
var code: URLSessionWebSocketTask.CloseCode?
38+
var reason: Data?
3739
func received(_ error: ParseError) {
3840
self.error = error
3941
}
42+
func closedSocket(_ code: URLSessionWebSocketTask.CloseCode?, reason: Data?) {
43+
self.code = code
44+
self.reason = reason
45+
}
4046
}
4147

4248
override func setUpWithError() throws {
@@ -418,6 +424,24 @@ class ParseLiveQueryTests: XCTestCase {
418424
}
419425
}
420426

427+
func testCloseFromServer() throws {
428+
guard let client = ParseLiveQuery.getDefault() else {
429+
throw ParseError(code: .unknownError,
430+
message: "Should be able to get client")
431+
}
432+
let delegate = TestDelegate()
433+
client.receiveDelegate = delegate
434+
client.task = URLSession.liveQuery.createTask(client.url)
435+
client.status(.closed, closeCode: .goingAway, reason: nil)
436+
let expectation1 = XCTestExpectation(description: "Response delegate")
437+
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
438+
XCTAssertEqual(delegate.code, .goingAway)
439+
XCTAssertNil(delegate.reason)
440+
expectation1.fulfill()
441+
}
442+
wait(for: [expectation1], timeout: 20.0)
443+
}
444+
421445
func testCloseAll() throws {
422446
guard let client = ParseLiveQuery.getDefault() else {
423447
XCTFail("Should be able to get client")

0 commit comments

Comments
 (0)