2424
2525import Foundation
2626
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-
3127extension String {
3228 private var length : Int {
3329 return countElements ( self )
@@ -55,18 +51,22 @@ class SocketEngine: NSObject, WebSocketDelegate {
5551 " parseQueue " . cStringUsingEncoding ( NSUTF8StringEncoding) , DISPATCH_QUEUE_SERIAL)
5652 private let handleQueue = dispatch_queue_create (
5753 " handleQueue " . cStringUsingEncoding ( NSUTF8StringEncoding) , DISPATCH_QUEUE_SERIAL)
54+ private let session : NSURLSession !
55+ private var _connected = false
56+ private var fastUpgrade = false
5857 private var forcePolling = false
5958 private var pingTimer : NSTimer ?
6059 private var postWait = [ String] ( )
6160 private var _polling = true
6261 private var probing = false
6362 private var probeWait = PollWaitQueue ( )
64- private let session : NSURLSession !
6563 private var waitingForPoll = false
6664 private var waitingForPost = false
6765 private var _websocket = false
6866 private var websocketConnected = false
69- var connected = false
67+ var connected : Bool {
68+ return self . _connected
69+ }
7070 var pingInterval : Int ?
7171 var polling : Bool {
7272 return self . _polling
@@ -142,14 +142,29 @@ class SocketEngine: NSObject, WebSocketDelegate {
142142 return ( urlPolling, urlWebSocket)
143143 }
144144
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+
145153 private func doPoll( ) {
146- if self . urlPolling == nil || self . websocket || self . waitingForPoll || !self . connected {
154+ if self . websocket || self . waitingForPoll || !self . connected {
147155 return
148156 }
149157
150- let req = NSMutableURLRequest ( URL: NSURL ( string: self . urlPolling! + " &sid= \( self . sid) " ) !)
151- req. timeoutInterval = 0.0
152158 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) " ) !)
153168
154169 self . session. dataTaskWithRequest ( req) { [ weak self] data, res, err in
155170 if self == nil {
@@ -158,29 +173,31 @@ class SocketEngine: NSObject, WebSocketDelegate {
158173 if self !. polling {
159174 self ? . handlePollingFailed ( err)
160175 }
176+
161177 return
162178 }
163-
164179 // println(data)
165180
166181 if let str = NSString ( data: data, encoding: NSUTF8StringEncoding) as? String {
167182 // println(str)
168183
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) }
177186 }
178187
179188 self ? . waitingForPoll = false
180- self ? . doPoll ( )
189+
190+ if self !. fastUpgrade {
191+ self ? . doFastUpgrade ( )
192+ return
193+ } else {
194+ self ? . doPoll ( )
195+ }
181196 } . resume ( )
182197 }
183198
199+
200+
184201 private func flushProbeWait( ) {
185202 // println("flushing probe wait")
186203 dispatch_async ( self . emitQueue) { [ weak self] in
@@ -227,7 +244,6 @@ class SocketEngine: NSObject, WebSocketDelegate {
227244 req. HTTPBody = postData
228245
229246 self . waitingForPost = true
230-
231247 self . session. dataTaskWithRequest ( req) { [ weak self] data, res, err in
232248 if self == nil {
233249 return
@@ -255,10 +271,11 @@ class SocketEngine: NSObject, WebSocketDelegate {
255271 }
256272
257273 // A poll failed, tell the client about it
258- // We check to see if we were closed by the server first
259274 private func handlePollingFailed( reason: NSError ? ) {
275+ assert ( self . polling, " Polling failed when we're not polling " )
276+
260277 if !self . client. reconnecting {
261- self . connected = false
278+ self . _connected = false
262279 self . ws? . disconnect ( )
263280 self . pingTimer? . invalidate ( )
264281 self . waitingForPoll = false
@@ -268,7 +285,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
268285 }
269286
270287 func open( opts: [ String : AnyObject ] ? = nil ) {
271- if self . waitingForPost || self . waitingForPoll || self . websocket || self . connected {
288+ if self . connected {
272289 assert ( false , " We're in a bad state, this shouldn't happen. " )
273290 }
274291
@@ -304,13 +321,12 @@ class SocketEngine: NSObject, WebSocketDelegate {
304321 return
305322 }
306323
307- self ? . connected = true
308-
309324 if let json = NSJSONSerialization . JSONObjectWithData ( jsonData!,
310325 options: NSJSONReadingOptions . AllowFragments, error: & err2) as? NSDictionary {
311326 if let sid = json [ " sid " ] as? String {
312327 // println(json)
313328 self ? . sid = sid
329+ self ? . _connected = true
314330
315331 if !self !. forcePolling {
316332 self ? . ws = WebSocket ( url: NSURL ( string: urlWebSocket + " &sid= \( self !. sid) " ) !)
@@ -363,7 +379,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
363379 length += chr
364380 } else {
365381 if length == " " || testLength ( length, & n) {
366- self . handlePollingFailed ( nil )
382+ println ( " failure in parsePollingMessage " )
367383 return
368384 }
369385
@@ -379,10 +395,8 @@ class SocketEngine: NSObject, WebSocketDelegate {
379395 if msg. length != 0 {
380396 // Be sure to capture the value of the msg
381397 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
386400 }
387401 }
388402
@@ -462,7 +476,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
462476 self ? . sendWebSocketMessage ( msg, withType: PacketType . MESSAGE, datas: datas)
463477 } else {
464478 // 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 )
466480 }
467481 }
468482 }
@@ -484,34 +498,34 @@ class SocketEngine: NSObject, WebSocketDelegate {
484498 if self . websocket {
485499 self . sendWebSocketMessage ( " " , withType: PacketType . PING)
486500 } else {
487- self . sendPollMessage ( " " , withType: PacketType . PING)
501+ self . sendPollMessage ( " " , withType: PacketType . PING, doPoll : false )
488502 }
489503 }
490504
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 ( )
502524 }
503- }
504-
505- if waitingForPost {
506- self . doPoll ( )
507- return
508- } else {
509- self . flushWaitingForPost ( )
510- }
511525 }
512526
513527 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)")
515529 self . ws? . writeString ( " \( type. rawValue) \( str) " )
516530
517531 if datas != nil {
@@ -539,12 +553,10 @@ class SocketEngine: NSObject, WebSocketDelegate {
539553
540554 private func upgradeTransport( ) {
541555 if self . websocketConnected {
556+ // Do a fast upgrade
557+ self . fastUpgrade = true
542558 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 )
548560 }
549561 }
550562
@@ -560,7 +572,7 @@ class SocketEngine: NSObject, WebSocketDelegate {
560572
561573 if self . websocket {
562574 self . pingTimer? . invalidate ( )
563- self . connected = false
575+ self . _connected = false
564576 self . _websocket = false
565577 self . _polling = true
566578 self . client. webSocketDidCloseWithCode ( 1 , reason: " Socket Disconnect " , wasClean: true )
0 commit comments