22
22
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
// THE SOFTWARE.
24
24
25
+ import Dispatch
25
26
import Foundation
26
27
27
28
public final class SocketIOClient : NSObject , SocketIOClientSpec , SocketEngineClient , SocketParsable {
@@ -41,43 +42,38 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
41
42
}
42
43
43
44
public var forceNew = false
45
+ public var handleQueue = DispatchQueue . main
44
46
public var nsp = " / "
45
47
public var config : SocketIOClientConfiguration
46
48
public var reconnects = true
47
49
public var reconnectWait = 10
48
50
49
51
private let logType = " SocketIOClient "
50
- private let parseQueue = DispatchQueue ( label: " com.socketio.parseQueue " )
51
52
52
53
private var anyHandler : ( ( SocketAnyEvent ) -> Void ) ?
53
54
private var currentReconnectAttempt = 0
54
55
private var handlers = [ SocketEventHandler] ( )
55
56
private var reconnecting = false
56
57
57
- private let ackSemaphore = DispatchSemaphore ( value: 1 )
58
58
private( set) var currentAck = - 1
59
- private( set) var handleQueue = DispatchQueue . main
60
59
private( set) var reconnectAttempts = - 1
61
-
62
- let ackQueue = DispatchQueue ( label: " com.socketio.ackQueue " )
63
- let emitQueue = DispatchQueue ( label: " com.socketio.emitQueue " )
64
60
65
61
var ackHandlers = SocketAckManager ( )
66
62
var waitingPackets = [ SocketPacket] ( )
67
-
63
+
68
64
public var sid : String ? {
69
65
return engine? . sid
70
66
}
71
-
67
+
72
68
/// Type safe way to create a new SocketIOClient. opts can be omitted
73
69
public init ( socketURL: URL , config: SocketIOClientConfiguration = [ ] ) {
74
70
self . config = config
75
71
self . socketURL = socketURL
76
-
72
+
77
73
if socketURL. absoluteString. hasPrefix ( " https:// " ) {
78
74
self . config. insert ( . secure( true ) )
79
75
}
80
-
76
+
81
77
for option in config {
82
78
switch option {
83
79
case let . reconnects( reconnects) :
@@ -102,10 +98,10 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
102
98
}
103
99
104
100
self . config. insert ( . path( " /socket.io/ " ) , replacing: false )
105
-
101
+
106
102
super. init ( )
107
103
}
108
-
104
+
109
105
/// Not so type safe way to create a SocketIOClient, meant for Objective-C compatiblity.
110
106
/// If using Swift it's recommended to use `init(socketURL: NSURL, options: Set<SocketIOClientOption>)`
111
107
public convenience init ( socketURL: NSURL , config: NSDictionary ? ) {
@@ -148,30 +144,25 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
148
144
} else {
149
145
engine? . connect ( )
150
146
}
151
-
147
+
152
148
guard timeoutAfter != 0 else { return }
153
149
154
150
let time = DispatchTime . now ( ) + Double( UInt64 ( timeoutAfter) * NSEC_PER_SEC) / Double( NSEC_PER_SEC)
155
151
156
152
handleQueue. asyncAfter ( deadline: time) { [ weak self] in
157
153
guard let this = self , this. status != . connected && this. status != . disconnected else { return }
158
-
154
+
159
155
this. status = . disconnected
160
156
this. engine? . disconnect ( reason: " Connect timeout " )
161
-
157
+
162
158
handler ? ( )
163
159
}
164
160
}
165
161
166
- private func nextAck( ) -> Int {
167
- ackSemaphore. wait ( )
168
- defer { ackSemaphore. signal ( ) }
162
+ private func createOnAck( _ items: [ Any ] ) -> OnAckCallback {
169
163
currentAck += 1
170
- return currentAck
171
- }
172
164
173
- private func createOnAck( _ items: [ Any ] ) -> OnAckCallback {
174
- return OnAckCallback ( ackNumber: nextAck ( ) , items: items, socket: self )
165
+ return OnAckCallback ( ackNumber: currentAck, items: items, socket: self )
175
166
}
176
167
177
168
func didConnect( ) {
@@ -214,7 +205,7 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
214
205
handleEvent ( " error " , data: [ " Tried emitting \( event) when not connected " ] , isInternalMessage: true )
215
206
return
216
207
}
217
-
208
+
218
209
_emit ( [ event] + items)
219
210
}
220
211
@@ -230,40 +221,40 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
230
221
}
231
222
232
223
func _emit( _ data: [ Any ] , ack: Int ? = nil ) {
233
- emitQueue. async {
234
- guard self . status == . connected else {
235
- self . handleEvent ( " error " , data: [ " Tried emitting when not connected " ] , isInternalMessage: true )
236
- return
237
- }
238
-
239
- let packet = SocketPacket . packetFromEmit ( data, id: ack ?? - 1 , nsp: self . nsp, ack: false )
240
- let str = packet. packetString
241
-
242
- DefaultSocketLogger . Logger. log ( " Emitting: %@ " , type: self . logType, args: str)
243
-
244
- self . engine? . send ( str, withData: packet. binary)
224
+ guard status == . connected else {
225
+ handleEvent ( " error " , data: [ " Tried emitting when not connected " ] , isInternalMessage: true )
226
+ return
245
227
}
228
+
229
+ let packet = SocketPacket . packetFromEmit ( data, id: ack ?? - 1 , nsp: nsp, ack: false )
230
+ let str = packet. packetString
231
+
232
+ DefaultSocketLogger . Logger. log ( " Emitting: %@ " , type: logType, args: str)
233
+
234
+ engine? . send ( str, withData: packet. binary)
246
235
}
247
236
248
237
// If the server wants to know that the client received data
249
238
func emitAck( _ ack: Int , with items: [ Any ] ) {
250
- emitQueue. async {
251
- guard self . status == . connected else { return }
252
-
253
- let packet = SocketPacket . packetFromEmit ( items, id: ack, nsp: self . nsp, ack: true )
254
- let str = packet. packetString
255
-
256
- DefaultSocketLogger . Logger. log ( " Emitting Ack: %@ " , type: self . logType, args: str)
257
-
258
- self . engine? . send ( str, withData: packet. binary)
259
- }
239
+ guard status == . connected else { return }
240
+
241
+ let packet = SocketPacket . packetFromEmit ( items, id: ack, nsp: nsp, ack: true )
242
+ let str = packet. packetString
243
+
244
+ DefaultSocketLogger . Logger. log ( " Emitting Ack: %@ " , type: logType, args: str)
245
+
246
+ engine? . send ( str, withData: packet. binary)
260
247
}
261
248
262
249
public func engineDidClose( reason: String ) {
263
- parseQueue . async {
264
- self . waitingPackets . removeAll ( )
250
+ handleQueue . async {
251
+ self . _engineDidClose ( reason : reason )
265
252
}
266
-
253
+ }
254
+
255
+ private func _engineDidClose( reason: String ) {
256
+ waitingPackets. removeAll ( )
257
+
267
258
if status != . disconnected {
268
259
status = . notConnected
269
260
}
@@ -276,13 +267,19 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
276
267
}
277
268
}
278
269
279
- /// error
280
270
public func engineDidError( reason: String ) {
271
+ handleQueue. async {
272
+ self . _engineDidError ( reason: reason)
273
+ }
274
+ }
275
+
276
+ /// error
277
+ private func _engineDidError( reason: String ) {
281
278
DefaultSocketLogger . Logger. error ( " %@ " , type: logType, args: reason)
282
279
283
280
handleEvent ( " error " , data: [ reason] , isInternalMessage: true )
284
281
}
285
-
282
+
286
283
public func engineDidOpen( reason: String ) {
287
284
DefaultSocketLogger . Logger. log ( reason, type: " SocketEngineClient " )
288
285
}
@@ -293,9 +290,7 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
293
290
294
291
DefaultSocketLogger . Logger. log ( " Handling ack: %@ with data: %@ " , type: logType, args: ack, data)
295
292
296
- handleQueue. async ( ) {
297
- self . ackHandlers. executeAck ( ack, with: data, onQueue: self . handleQueue)
298
- }
293
+ ackHandlers. executeAck ( ack, with: data, onQueue: handleQueue)
299
294
}
300
295
301
296
/// Causes an event to be handled. Only use if you know what you're doing.
@@ -304,12 +299,10 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
304
299
305
300
DefaultSocketLogger . Logger. log ( " Handling event: %@ with data: %@ " , type: logType, args: event, data)
306
301
307
- handleQueue. async {
308
- self . anyHandler ? ( SocketAnyEvent ( event: event, items: data) )
302
+ anyHandler ? ( SocketAnyEvent ( event: event, items: data) )
309
303
310
- for handler in self . handlers where handler. event == event {
311
- handler. executeCallback ( with: data, withAck: ack, withSocket: self )
312
- }
304
+ for handler in handlers where handler. event == event {
305
+ handler. executeCallback ( with: data, withAck: ack, withSocket: self )
313
306
}
314
307
}
315
308
@@ -384,17 +377,17 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
384
377
public func parseEngineMessage( _ msg: String ) {
385
378
DefaultSocketLogger . Logger. log ( " Should parse message: %@ " , type: " SocketIOClient " , args: msg)
386
379
387
- parseQueue . async { self . parseSocketMessage ( msg) }
380
+ handleQueue . async { self . parseSocketMessage ( msg) }
388
381
}
389
382
390
383
public func parseEngineBinaryData( _ data: Data ) {
391
- parseQueue . async { self . parseBinaryData ( data) }
384
+ handleQueue . async { self . parseBinaryData ( data) }
392
385
}
393
386
394
387
/// Tries to reconnect to the server.
395
388
public func reconnect( ) {
396
389
guard !reconnecting else { return }
397
-
390
+
398
391
engine? . disconnect ( reason: " manual reconnect " )
399
392
}
400
393
@@ -409,7 +402,7 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
409
402
410
403
DefaultSocketLogger . Logger. log ( " Starting reconnect " , type: logType)
411
404
handleEvent ( " reconnect " , data: [ reason] , isInternalMessage: true )
412
-
405
+
413
406
_tryReconnect ( )
414
407
}
415
408
@@ -425,26 +418,24 @@ public final class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineCl
425
418
426
419
currentReconnectAttempt += 1
427
420
connect ( )
428
-
429
- let deadline = DispatchTime . now ( ) + Double( Int64 ( UInt64 ( reconnectWait) * NSEC_PER_SEC) ) / Double( NSEC_PER_SEC)
430
-
431
- DispatchQueue . main. asyncAfter ( deadline: deadline, execute: _tryReconnect)
421
+
422
+ handleQueue. asyncAfter ( deadline: DispatchTime . now ( ) + Double( reconnectWait) , execute: _tryReconnect)
432
423
}
433
-
424
+
434
425
// Test properties
435
-
426
+
436
427
var testHandlers : [ SocketEventHandler ] {
437
428
return handlers
438
429
}
439
-
430
+
440
431
func setTestable( ) {
441
432
status = . connected
442
433
}
443
-
434
+
444
435
func setTestEngine( _ engine: SocketEngineSpec ? ) {
445
436
self . engine = engine
446
437
}
447
-
438
+
448
439
func emitTest( event: String , _ data: Any ... ) {
449
440
_emit ( [ event] + data)
450
441
}
0 commit comments