Skip to content

Commit 5b49a59

Browse files
committed
fix (avoid) handling of websocket delegate methods for disconnected websocket; improve logging
1 parent d5cccf1 commit 5b49a59

9 files changed

+132
-80
lines changed

Source/SocketIO/Client/SocketIOClient.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ open class SocketIOClient: NSObject, SocketIOClientSpec {
182182
/// Called when the client has disconnected from socket.io.
183183
///
184184
/// - parameter reason: The reason for the disconnection.
185-
open func didDisconnect(reason: String) {
185+
open func didDisconnect(reason: SocketConnectionChangeReason) {
186186
guard status != .disconnected else { return }
187187

188188
DefaultSocketLogger.Logger.log("Disconnected: \(reason)", type: logType)
@@ -307,7 +307,7 @@ open class SocketIOClient: NSObject, SocketIOClientSpec {
307307

308308
guard status == .connected else {
309309
wrappedCompletion?()
310-
handleClientEvent(.error, data: ["Tried emitting when not connected"])
310+
handleClientEvent(.error, data: [SocketError.triedEmittingWhenNotConnected])
311311
return
312312
}
313313

@@ -382,7 +382,7 @@ open class SocketIOClient: NSObject, SocketIOClientSpec {
382382
case .connect:
383383
didConnect(toNamespace: nsp, payload: packet.data.isEmpty ? nil : packet.data[0] as? [String: Any])
384384
case .disconnect:
385-
didDisconnect(reason: "Got Disconnect")
385+
didDisconnect(reason: .gotDisconnectPacket)
386386
case .error:
387387
handleEvent("error", data: packet.data, isInternalMessage: true, withAck: packet.id)
388388
}
@@ -522,7 +522,7 @@ open class SocketIOClient: NSObject, SocketIOClientSpec {
522522
/// Called when the manager detects a broken connection, or when a manual reconnect is triggered.
523523
///
524524
/// - parameter reason: The reason this socket is reconnecting.
525-
open func setReconnecting(reason: String) {
525+
open func setReconnecting(reason: SocketConnectionChangeReason) {
526526
status = .connecting
527527

528528
handleClientEvent(.reconnect, data: [reason])

Source/SocketIO/Client/SocketIOClientSpec.swift

+6-6
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ public protocol SocketIOClientSpec : AnyObject {
8888
/// Called when the client has disconnected from socket.io.
8989
///
9090
/// - parameter reason: The reason for the disconnection.
91-
func didDisconnect(reason: String)
91+
func didDisconnect(reason: SocketConnectionChangeReason)
9292

9393
/// Called when the client encounters an error.
9494
///
9595
/// - parameter reason: The reason for the disconnection.
96-
func didError(reason: String)
96+
func didError(error: SocketError)
9797

9898
/// Disconnects the socket.
9999
func disconnect()
@@ -271,15 +271,15 @@ public protocol SocketIOClientSpec : AnyObject {
271271
/// Called when the manager detects a broken connection, or when a manual reconnect is triggered.
272272
///
273273
/// parameter reason: The reason this socket is going reconnecting.
274-
func setReconnecting(reason: String)
274+
func setReconnecting(reason: SocketConnectionChangeReason)
275275
}
276276

277277
public extension SocketIOClientSpec {
278278
/// Default implementation.
279-
func didError(reason: String) {
280-
DefaultSocketLogger.Logger.error("\(reason)", type: "SocketIOClient")
279+
func didError(error: SocketError) {
280+
DefaultSocketLogger.Logger.error("\(error)", type: "SocketIOClient")
281281

282-
handleClientEvent(.error, data: [reason])
282+
handleClientEvent(.error, data: [error])
283283
}
284284
}
285285

Source/SocketIO/Engine/SocketEngine.swift

+49-37
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,9 @@ open class SocketEngine:
198198
2: Bad handshake request
199199
3: Bad request
200200
*/
201-
didError(reason: error)
201+
didError(error: .engineErrorMessage(error))
202202
} catch {
203-
client?.engineDidError(reason: "Got unknown error from server \(msg)")
203+
client?.engineDidError(error: .engineUnknownMessage(msg))
204204
}
205205
}
206206

@@ -214,12 +214,13 @@ open class SocketEngine:
214214
}
215215
}
216216

217-
private func closeOutEngine(reason: String) {
217+
private func closeOutEngine(reason: SocketConnectionChangeReason) {
218218
sid = ""
219219
closed = true
220220
invalidated = true
221221
connected = false
222-
222+
// nil out the delegate here; we're getting callbacks from the old socket when closing and recreating the WS
223+
ws?.delegate = nil
223224
ws?.disconnect()
224225
stopPolling()
225226
client?.engineDidClose(reason: reason)
@@ -236,7 +237,7 @@ open class SocketEngine:
236237
if connected {
237238
DefaultSocketLogger.Logger.error("Engine tried opening while connected. Assuming this was a reconnect",
238239
type: SocketEngine.logType)
239-
_disconnect(reason: "reconnect")
240+
_disconnect(reason: .socketError(.triedOpeningWhileConnected))
240241
}
241242

242243
DefaultSocketLogger.Logger.log("Starting engine. Server: \(url)", type: SocketEngine.logType)
@@ -315,25 +316,25 @@ open class SocketEngine:
315316
}
316317

317318
/// Called when an error happens during execution. Causes a disconnection.
318-
open func didError(reason: String) {
319-
DefaultSocketLogger.Logger.error("\(reason)", type: SocketEngine.logType)
320-
client?.engineDidError(reason: reason)
321-
disconnect(reason: reason)
319+
open func didError(error: SocketError) {
320+
DefaultSocketLogger.Logger.error("\(error)", type: SocketEngine.logType)
321+
client?.engineDidError(error: error)
322+
disconnect(reason: .socketError(error))
322323
}
323324

324325
/// Disconnects from the server.
325326
///
326327
/// - parameter reason: The reason for the disconnection. This is communicated up to the client.
327-
open func disconnect(reason: String) {
328+
open func disconnect(reason: SocketConnectionChangeReason) {
328329
engineQueue.async {
329330
self._disconnect(reason: reason)
330331
}
331332
}
332333

333-
private func _disconnect(reason: String) {
334+
private func _disconnect(reason: SocketConnectionChangeReason) {
334335
guard connected && !closed else { return closeOutEngine(reason: reason) }
335336

336-
DefaultSocketLogger.Logger.log("Engine is being closed.", type: SocketEngine.logType)
337+
DefaultSocketLogger.Logger.log("Engine is being closed. \(reason)", type: SocketEngine.logType)
337338

338339
if polling {
339340
disconnectPolling(reason: reason)
@@ -345,7 +346,7 @@ open class SocketEngine:
345346

346347
// We need to take special care when we're polling that we send it ASAP
347348
// Also make sure we're on the emitQueue since we're touching postWait
348-
private func disconnectPolling(reason: String) {
349+
private func disconnectPolling(reason: SocketConnectionChangeReason) {
349350
postWait.append((String(SocketEnginePacketType.close.rawValue), {}))
350351

351352
doRequest(for: createRequestForPostWithPostWait()) {_, _, _ in }
@@ -402,7 +403,7 @@ open class SocketEngine:
402403
postWait.removeAll(keepingCapacity: false)
403404
}
404405

405-
private func handleClose(_ reason: String) {
406+
private func handleClose(_ reason: SocketConnectionChangeReason) {
406407
client?.engineDidClose(reason: reason)
407408
}
408409

@@ -416,13 +417,13 @@ open class SocketEngine:
416417

417418
private func handleOpen(openData: String) {
418419
guard let json = try? openData.toDictionary() else {
419-
didError(reason: "Error parsing open packet")
420+
didError(error: .openPacketUnparseable)
420421

421422
return
422423
}
423424

424425
guard let sid = json["sid"] as? String else {
425-
didError(reason: "Open packet contained no sid")
426+
didError(error: .openPacketMissingSID)
426427

427428
return
428429
}
@@ -458,7 +459,7 @@ open class SocketEngine:
458459
doPoll()
459460
}
460461

461-
client?.engineDidOpen(reason: "Connect")
462+
client?.engineDidOpen(reason: .engineOpen)
462463
}
463464

464465
private func handlePong(with message: String) {
@@ -492,8 +493,9 @@ open class SocketEngine:
492493
// Make sure not to ping old connections
493494
guard let this = self, this.sid == id else { return }
494495

495-
if abs(this.lastCommunication?.timeIntervalSinceNow ?? deadlineMs) >= deadlineMs {
496-
this.closeOutEngine(reason: "Ping timeout")
496+
let actualTime = this.lastCommunication?.timeIntervalSinceNow ?? deadlineMs
497+
if abs(actualTime) >= deadlineMs {
498+
this.closeOutEngine(reason: .socketError(.pingTimeout(actualTime)))
497499
} else {
498500
this.checkPings()
499501
}
@@ -541,7 +543,7 @@ open class SocketEngine:
541543
case .open:
542544
handleOpen(openData: String(message.dropFirst()))
543545
case .close:
544-
handleClose(message)
546+
handleClose(.engineCloseMessage(message))
545547
default:
546548
DefaultSocketLogger.Logger.log("Got unknown packet type", type: SocketEngine.logType)
547549
}
@@ -571,7 +573,7 @@ open class SocketEngine:
571573

572574
// Server is not responding
573575
if pongsMissed > pongsMissedMax {
574-
closeOutEngine(reason: "Ping timeout")
576+
closeOutEngine(reason: .socketError(.pongsMissed(pongsMissed)))
575577
return
576578
}
577579

@@ -687,12 +689,11 @@ open class SocketEngine:
687689
}
688690
}
689691

690-
private func websocketDidDisconnect(error: Error?) {
692+
private func websocketDidDisconnect(reason: SocketConnectionChangeReason) {
691693
probing = false
692694

693695
if closed {
694-
client?.engineDidClose(reason: "Disconnect")
695-
696+
client?.engineDidClose(reason: reason)
696697
return
697698
}
698699

@@ -705,12 +706,13 @@ open class SocketEngine:
705706
connected = false
706707
polling = true
707708

708-
if let error = error as? WSError {
709-
didError(reason: "\(error.message). code=\(error.code), type=\(error.type)")
710-
} else if let reason = error?.localizedDescription {
711-
didError(reason: reason)
712-
} else {
713-
client?.engineDidClose(reason: "Socket Disconnected")
709+
//following existing patterns for these, just cleaning up a bit
710+
switch(reason) {
711+
case .socketError(let error):
712+
didError(error: error)
713+
default:
714+
//following existing pattern, we close ourselves out here
715+
client?.engineDidClose(reason: reason)
714716
}
715717
}
716718

@@ -728,37 +730,47 @@ extension SocketEngine {
728730
public func URLSession(session: URLSession, didBecomeInvalidWithError error: NSError?) {
729731
DefaultSocketLogger.Logger.error("Engine URLSession became invalid", type: "SocketEngine")
730732

731-
didError(reason: "Engine URLSession became invalid")
733+
didError(error: .urlSessionBecameInvalid(error))
732734
}
733735
}
734736

735-
enum EngineError: Error {
736-
case canceled
737-
}
737+
//enum EngineError: Error {
738+
// case canceled
739+
//}
738740

739741
extension SocketEngine {
740742
/// Delegate method for WebSocketDelegate.
741743
///
742744
/// - Parameters:
743745
/// - event: WS Event
744746
/// - _:
745-
public func didReceive(event: WebSocketEvent, client _: WebSocket) {
747+
public func didReceive(event: WebSocketEvent, client websocket: WebSocket) {
748+
guard websocket === self.ws else {
749+
DefaultSocketLogger.Logger.log("Ignoring websocket event from wrong client: \(event)", type: SocketEngine.logType)
750+
return
751+
}
746752
switch event {
747753
case let .connected(headers):
748754
wsConnected = true
749755
client?.engineDidWebsocketUpgrade(headers: headers)
750756
websocketDidConnect()
751757
case .cancelled:
752758
wsConnected = false
753-
websocketDidDisconnect(error: EngineError.canceled)
759+
websocketDidDisconnect(reason: .websocketEngineCanceled)
754760
case let .disconnected(reason, code):
755761
wsConnected = false
756-
websocketDidDisconnect(error: nil)
762+
websocketDidDisconnect(reason: .socketError(.websocketEngineDisconnected(reason, Int(code))))
757763
case let .text(msg):
758764
parseEngineMessage(msg)
759765
case let .binary(data):
760766
parseEngineData(data)
767+
case let .error(error):
768+
DefaultSocketLogger.Logger.error("didReceive WebSocket error \(error as Any)", type: "SocketEngine")
769+
//share the error with the clients.
770+
client?.engineDidError(error: .websocketEngineError(error))
771+
761772
case _:
773+
//TODO: Handle or log other cases?
762774
break
763775
}
764776
}

Source/SocketIO/Engine/SocketEngineClient.swift

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,23 @@
2626
import Foundation
2727

2828
/// Declares that a type will be a delegate to an engine.
29-
@objc public protocol SocketEngineClient {
29+
public protocol SocketEngineClient: AnyObject {
3030
// MARK: Methods
3131

3232
/// Called when the engine errors.
3333
///
3434
/// - parameter reason: The reason the engine errored.
35-
func engineDidError(reason: String)
35+
func engineDidError(error: SocketError)
3636

3737
/// Called when the engine closes.
3838
///
3939
/// - parameter reason: The reason that the engine closed.
40-
func engineDidClose(reason: String)
40+
func engineDidClose(reason: SocketConnectionChangeReason)
4141

4242
/// Called when the engine opens.
4343
///
4444
/// - parameter reason: The reason the engine opened.
45-
func engineDidOpen(reason: String)
45+
func engineDidOpen(reason: SocketConnectionChangeReason)
4646

4747
/// Called when the engine receives a ping message. Only called in socket.io >3.
4848
func engineDidReceivePing()

Source/SocketIO/Engine/SocketEnginePollable.swift

+7-7
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ extension SocketEnginePollable {
137137
}
138138

139139
if this.polling {
140-
this.didError(reason: err?.localizedDescription ?? "Error")
140+
this.didError(error: .urlSessionError(err))
141141
}
142142

143143
return
@@ -173,17 +173,17 @@ extension SocketEnginePollable {
173173

174174
DefaultSocketLogger.Logger.log("POSTing", type: "SocketEnginePolling")
175175

176-
doRequest(for: req) {[weak self] _, res, err in
176+
doRequest(for: req) {[weak self] _, responseOpt, errorOpt in
177177
guard let this = self else { return }
178-
guard let res = res as? HTTPURLResponse, res.statusCode == 200 else {
179-
if let err = err {
180-
DefaultSocketLogger.Logger.error(err.localizedDescription, type: "SocketEnginePolling")
178+
guard let response = responseOpt as? HTTPURLResponse, response.statusCode == 200 else {
179+
if let error = errorOpt {
180+
DefaultSocketLogger.Logger.error(error.localizedDescription, type: "SocketEnginePolling")
181181
} else {
182-
DefaultSocketLogger.Logger.error("Error flushing waiting posts", type: "SocketEnginePolling")
182+
DefaultSocketLogger.Logger.error("Error flushing waiting posts: \((responseOpt as? HTTPURLResponse)?.statusCode ?? -1)", type: "SocketEnginePolling")
183183
}
184184

185185
if this.polling {
186-
this.didError(reason: err?.localizedDescription ?? "Error")
186+
this.didError(error: .urlSessionError(errorOpt))
187187
}
188188

189189
return

Source/SocketIO/Engine/SocketEngineSpec.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,12 @@ public protocol SocketEngineSpec: class {
106106
func connect()
107107

108108
/// Called when an error happens during execution. Causes a disconnection.
109-
func didError(reason: String)
109+
func didError(error: SocketError)
110110

111111
/// Disconnects from the server.
112112
///
113113
/// - parameter reason: The reason for the disconnection. This is communicated up to the client.
114-
func disconnect(reason: String)
114+
func disconnect(reason: SocketConnectionChangeReason)
115115

116116
/// Called to switch from HTTP long-polling to WebSockets. After calling this method the engine will be in
117117
/// WebSocket mode.

0 commit comments

Comments
 (0)