24
24
25
25
import Foundation
26
26
27
- // This is used because in Swift 1.1, turning on -O causes a
28
- // memory access violation in SocketEngine#parseEngineMessage
29
- private var fixSwift : AnyObject ?
30
-
31
27
extension String {
32
28
private var length : Int {
33
29
return countElements ( self )
@@ -55,18 +51,22 @@ class SocketEngine: NSObject, WebSocketDelegate {
55
51
" parseQueue " . cStringUsingEncoding ( NSUTF8StringEncoding) , DISPATCH_QUEUE_SERIAL)
56
52
private let handleQueue = dispatch_queue_create (
57
53
" handleQueue " . cStringUsingEncoding ( NSUTF8StringEncoding) , DISPATCH_QUEUE_SERIAL)
54
+ private let session : NSURLSession !
55
+ private var _connected = false
56
+ private var fastUpgrade = false
58
57
private var forcePolling = false
59
58
private var pingTimer : NSTimer ?
60
59
private var postWait = [ String] ( )
61
60
private var _polling = true
62
61
private var probing = false
63
62
private var probeWait = PollWaitQueue ( )
64
- private let session : NSURLSession !
65
63
private var waitingForPoll = false
66
64
private var waitingForPost = false
67
65
private var _websocket = false
68
66
private var websocketConnected = false
69
- var connected = false
67
+ var connected : Bool {
68
+ return self . _connected
69
+ }
70
70
var pingInterval : Int ?
71
71
var polling : Bool {
72
72
return self . _polling
@@ -142,14 +142,29 @@ class SocketEngine: NSObject, WebSocketDelegate {
142
142
return ( urlPolling, urlWebSocket)
143
143
}
144
144
145
+ private func doFastUpgrade( ) {
146
+ self . sendWebSocketMessage ( " " , withType: PacketType . UPGRADE)
147
+ self . _websocket = true
148
+ self . _polling = false
149
+ self . fastUpgrade = false
150
+ self . flushProbeWait ( )
151
+ }
152
+
145
153
private func doPoll( ) {
146
- if self . urlPolling == nil || self . websocket || self . waitingForPoll || !self . connected {
154
+ if self . websocket || self . waitingForPoll || !self . connected {
147
155
return
148
156
}
149
157
150
- let req = NSMutableURLRequest ( URL: NSURL ( string: self . urlPolling! + " &sid= \( self . sid) " ) !)
151
- req. timeoutInterval = 0.0
152
158
self . waitingForPoll = true
159
+ self . doRequest ( self . parsePollingMessage)
160
+ }
161
+
162
+ private func doRequest( callback: ( String ) -> Void ) {
163
+ if !self . polling {
164
+ return
165
+ }
166
+
167
+ let req = NSURLRequest ( URL: NSURL ( string: self . urlPolling! + " &sid= \( self . sid) " ) !)
153
168
154
169
self . session. dataTaskWithRequest ( req) { [ weak self] data, res, err in
155
170
if self == nil {
@@ -158,29 +173,31 @@ class SocketEngine: NSObject, WebSocketDelegate {
158
173
if self !. polling {
159
174
self ? . handlePollingFailed ( err)
160
175
}
176
+
161
177
return
162
178
}
163
-
164
179
// println(data)
165
180
166
181
if let str = NSString ( data: data, encoding: NSUTF8StringEncoding) as? String {
167
182
// println(str)
168
183
169
- dispatch_async ( self !. parseQueue) { [ weak self] in
170
- if self == nil {
171
- return
172
- }
173
-
174
- self ? . parsePollingMessage ( str)
175
- return
176
- }
184
+
185
+ dispatch_async ( self !. parseQueue) { callback ( str) }
177
186
}
178
187
179
188
self ? . waitingForPoll = false
180
- self ? . doPoll ( )
189
+
190
+ if self !. fastUpgrade {
191
+ self ? . doFastUpgrade ( )
192
+ return
193
+ } else {
194
+ self ? . doPoll ( )
195
+ }
181
196
} . resume ( )
182
197
}
183
198
199
+
200
+
184
201
private func flushProbeWait( ) {
185
202
// println("flushing probe wait")
186
203
dispatch_async ( self . emitQueue) { [ weak self] in
@@ -227,7 +244,6 @@ class SocketEngine: NSObject, WebSocketDelegate {
227
244
req. HTTPBody = postData
228
245
229
246
self . waitingForPost = true
230
-
231
247
self . session. dataTaskWithRequest ( req) { [ weak self] data, res, err in
232
248
if self == nil {
233
249
return
@@ -255,10 +271,11 @@ class SocketEngine: NSObject, WebSocketDelegate {
255
271
}
256
272
257
273
// A poll failed, tell the client about it
258
- // We check to see if we were closed by the server first
259
274
private func handlePollingFailed( reason: NSError ? ) {
275
+ assert ( self . polling, " Polling failed when we're not polling " )
276
+
260
277
if !self . client. reconnecting {
261
- self . connected = false
278
+ self . _connected = false
262
279
self . ws? . disconnect ( )
263
280
self . pingTimer? . invalidate ( )
264
281
self . waitingForPoll = false
@@ -268,7 +285,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
268
285
}
269
286
270
287
func open( opts: [ String : AnyObject ] ? = nil ) {
271
- if self . waitingForPost || self . waitingForPoll || self . websocket || self . connected {
288
+ if self . connected {
272
289
assert ( false , " We're in a bad state, this shouldn't happen. " )
273
290
}
274
291
@@ -304,13 +321,12 @@ class SocketEngine: NSObject, WebSocketDelegate {
304
321
return
305
322
}
306
323
307
- self ? . connected = true
308
-
309
324
if let json = NSJSONSerialization . JSONObjectWithData ( jsonData!,
310
325
options: NSJSONReadingOptions . AllowFragments, error: & err2) as? NSDictionary {
311
326
if let sid = json [ " sid " ] as? String {
312
327
// println(json)
313
328
self ? . sid = sid
329
+ self ? . _connected = true
314
330
315
331
if !self !. forcePolling {
316
332
self ? . ws = WebSocket ( url: NSURL ( string: urlWebSocket + " &sid= \( self !. sid) " ) !)
@@ -363,7 +379,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
363
379
length += chr
364
380
} else {
365
381
if length == " " || testLength ( length, & n) {
366
- self . handlePollingFailed ( nil )
382
+ println ( " failure in parsePollingMessage " )
367
383
return
368
384
}
369
385
@@ -379,10 +395,8 @@ class SocketEngine: NSObject, WebSocketDelegate {
379
395
if msg. length != 0 {
380
396
// Be sure to capture the value of the msg
381
397
dispatch_async ( self . handleQueue) { [ weak self, msg] in
382
- fixSwift = msg
383
- if fixSwift is String {
384
- self ? . parseEngineMessage ( fixSwift as String )
385
- }
398
+ self ? . parseEngineMessage ( msg)
399
+ return
386
400
}
387
401
}
388
402
@@ -462,7 +476,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
462
476
self ? . sendWebSocketMessage ( msg, withType: PacketType . MESSAGE, datas: datas)
463
477
} else {
464
478
// println("sending poll: \(msg):\(datas)")
465
- self ? . sendPollMessage ( msg, withType: PacketType . MESSAGE, datas: datas)
479
+ self ? . sendPollMessage ( msg, withType: PacketType . MESSAGE, datas: datas, doPoll : true )
466
480
}
467
481
}
468
482
}
@@ -484,34 +498,34 @@ class SocketEngine: NSObject, WebSocketDelegate {
484
498
if self . websocket {
485
499
self . sendWebSocketMessage ( " " , withType: PacketType . PING)
486
500
} else {
487
- self . sendPollMessage ( " " , withType: PacketType . PING)
501
+ self . sendPollMessage ( " " , withType: PacketType . PING, doPoll : false )
488
502
}
489
503
}
490
504
491
- private func sendPollMessage( msg: String , withType type: PacketType , datas: [ NSData ] ? = nil ) {
492
- // println("Sending: poll: \(msg) as type: \(type.rawValue)")
493
- let strMsg = " \( type. rawValue) \( msg) "
494
-
495
- self . postWait. append ( strMsg)
496
-
497
- if datas != nil {
498
- for data in datas! {
499
- let ( nilData, b64Data) = self . createBinaryDataForSend ( data)
500
-
501
- self . postWait. append ( b64Data!)
505
+ private func sendPollMessage( msg: String , withType type: PacketType ,
506
+ datas: [ NSData ] ? = nil , doPoll poll: Bool ) {
507
+ // println("Sending poll: \(msg) as type: \(type.rawValue)")
508
+ let strMsg = " \( type. rawValue) \( msg) "
509
+
510
+ self . postWait. append ( strMsg)
511
+
512
+ if datas != nil {
513
+ for data in datas! {
514
+ let ( nilData, b64Data) = self . createBinaryDataForSend ( data)
515
+
516
+ self . postWait. append ( b64Data!)
517
+ }
518
+ }
519
+
520
+ if !self . waitingForPoll && self . waitingForPost && poll {
521
+ self . doPoll ( )
522
+ } else {
523
+ self . flushWaitingForPost ( )
502
524
}
503
- }
504
-
505
- if waitingForPost {
506
- self . doPoll ( )
507
- return
508
- } else {
509
- self . flushWaitingForPost ( )
510
- }
511
525
}
512
526
513
527
private func sendWebSocketMessage( str: String , withType type: PacketType , datas: [ NSData ] ? = nil ) {
514
- // println("Sending: ws: \(str) as type: \(type.rawValue)")
528
+ // println("Sending ws: \(str) as type: \(type.rawValue)")
515
529
self . ws? . writeString ( " \( type. rawValue) \( str) " )
516
530
517
531
if datas != nil {
@@ -539,12 +553,10 @@ class SocketEngine: NSObject, WebSocketDelegate {
539
553
540
554
private func upgradeTransport( ) {
541
555
if self . websocketConnected {
556
+ // Do a fast upgrade
557
+ self . fastUpgrade = true
542
558
self . probing = false
543
- self . _websocket = true
544
- self . waitingForPoll = false
545
- self . _polling = false
546
- self . sendWebSocketMessage ( " " , withType: PacketType . UPGRADE)
547
- self . flushProbeWait ( )
559
+ self . sendPollMessage ( " " , withType: PacketType . NOOP, doPoll: false )
548
560
}
549
561
}
550
562
@@ -560,7 +572,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
560
572
561
573
if self . websocket {
562
574
self . pingTimer? . invalidate ( )
563
- self . connected = false
575
+ self . _connected = false
564
576
self . _websocket = false
565
577
self . _polling = true
566
578
self . client. webSocketDidCloseWithCode ( 1 , reason: " Socket Disconnect " , wasClean: true )
0 commit comments