From 6e56869ef0f4f6661cd89a65ad9384872df125e0 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 6 Apr 2015 09:30:22 -0400 Subject: [PATCH 1/5] add note about emitwithack --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 447a32f..aeed460 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,8 @@ Methods 2. `onAny(callback:((event:String, items:AnyObject?)) -> Void)` - Adds a handler for all events. It will be called on any received event. 3. `emit(event:String, _ items:AnyObject...)` - Sends a message. Can send multiple items. 4. `emitObjc(event:String, withItems items:[AnyObject])` - `emit` for Objective-C -5. `emitWithAck(event:String, _ items:AnyObject...) -> (timeout:UInt64, callback:(NSArray?) -> Void) -> Void` - Sends a message that requests an acknowledgement from the server. Returns a function which you can use to add a handler. See example. -6. `emitWithAckObjc(event:String, withItems items:[AnyObject]) -> (UInt64, (NSArray?) -> Void) -> Void` - `emitWithAck` for Objective-C. +5. `emitWithAck(event:String, _ items:AnyObject...) -> (timeout:UInt64, callback:(NSArray?) -> Void) -> Void` - Sends a message that requests an acknowledgement from the server. Returns a function which you can use to add a handler. See example. Note: The message is not sent until you call the returned function. +6. `emitWithAckObjc(event:String, withItems items:[AnyObject]) -> (UInt64, (NSArray?) -> Void) -> Void` - `emitWithAck` for Objective-C. Note: The message is not sent until you call the returned function. 7. `connect()` - Establishes a connection to the server. A "connect" event is fired upon successful connection. 8. `connectWithParams(params:[String: AnyObject])` - Establishes a connection to the server passing the specified params. A "connect" event is fired upon successful connection. 9. `close(#fast:Bool)` - Closes the socket. Once a socket is closed it should not be reopened. Pass true to fast if you're closing from a background task. From 9489676009d15d9d8ff91670b752d3657eaa2b99 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 6 Apr 2015 11:56:47 -0400 Subject: [PATCH 2/5] use weak references to client --- SwiftIO/SocketEngine.swift | 72 ++++++++++++++++++++++++------------ SwiftIO/SocketIOClient.swift | 1 + 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index dae5a05..38605cd 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -44,7 +44,6 @@ public enum PacketType:String { } public class SocketEngine: NSObject, WebSocketDelegate { - unowned let client:SocketEngineClient private let workQueue = NSOperationQueue() private let emitQueue = dispatch_queue_create( "engineEmitQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) @@ -70,6 +69,8 @@ public class SocketEngine: NSObject, WebSocketDelegate { var connected:Bool { return self._connected } + + weak var client:SocketEngineClient? var cookies:[NSHTTPCookie]? var pingInterval:Int? var polling:Bool { @@ -97,16 +98,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.pingTimer?.invalidate() self.closed = true - if self.polling { - self.write("", withType: PacketType.CLOSE, withData: nil) - self.client.didForceClose("Disconnect") - } else { - self.ws?.disconnect() - - if fast { - self.client.didForceClose("Fast Disconnect") - } + self.write("", withType: PacketType.CLOSE, withData: nil) + self.ws?.disconnect() + + if fast || self.polling { + self.client?.didForceClose("Disconnect") } + + self.client = nil } private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) { @@ -126,11 +125,15 @@ public class SocketEngine: NSObject, WebSocketDelegate { } private func createURLs(params:[String: AnyObject]?) -> (String, String) { - var url = "\(self.client.socketURL)/socket.io/?transport=" + if self.client == nil { + return ("", "") + } + + var url = "\(self.client!.socketURL)/socket.io/?transport=" var urlPolling:String var urlWebSocket:String - if self.client.secure { + if self.client!.secure { urlPolling = "https://" + url + "polling" urlWebSocket = "wss://" + url + "websocket" } else { @@ -320,10 +323,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.waitingForPoll = false self.waitingForPost = false - if !self.closed && !self.client.reconnecting { - self.client.pollingDidFail(reason) - } else if !self.client.reconnecting { - self.client.didForceClose(reason) + if self.client == nil { + return + } + + if !self.closed && !self.client!.reconnecting { + self.client?.pollingDidFail(reason) + } else if !self.client!.reconnecting { + self.client?.didForceClose(reason) } } @@ -413,8 +420,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { } private func parseEngineData(data:NSData) { - dispatch_async(self.client.handleQueue) {[weak self] in - self?.client.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1))) + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1))) return } } @@ -438,8 +449,13 @@ public class SocketEngine: NSObject, WebSocketDelegate { if let data = NSData(base64EncodedString: message, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) { // println("sending \(data)") - dispatch_async(self.client.handleQueue) {[weak self] in - self?.client.parseBinaryData(data) + + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseBinaryData(data) return } } @@ -491,8 +507,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { return } else if type == PacketType.CLOSE.rawValue { + if self.client == nil { + return + } + if self.polling { - self.client.didForceClose("Disconnect") + self.client!.didForceClose("Disconnect") } return @@ -504,8 +524,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { // Remove message type message.removeAtIndex(message.startIndex) - dispatch_async(self.client.handleQueue) {[weak self] in - self?.client.parseSocketMessage(message) + if self.client == nil { + return + } + + dispatch_async(self.client!.handleQueue) {[weak self] in + self?.client?.parseSocketMessage(message) return } } @@ -633,7 +657,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { self._websocket = false let reason = error?.localizedDescription - self.client.webSocketDidCloseWithCode(1, + self.client?.webSocketDidCloseWithCode(1, reason: reason == nil ? "Socket Disconnected" : reason!) } else { self.flushProbeWait() diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index b593ac8..455ff29 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -204,6 +204,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { if timeout != 0 { let time = dispatch_time(DISPATCH_TIME_NOW, Int64(timeout * NSEC_PER_SEC)) + dispatch_after(time, dispatch_get_main_queue()) { self?.ackHandlers.timeoutAck(ack) return From a4e81fee6adb82687bfd40d65efe1040d7c7de1e Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 6 Apr 2015 12:49:39 -0400 Subject: [PATCH 3/5] fix outstanding poll messages after switch to websockets --- SwiftIO/SocketEngine.swift | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index 38605cd..ff0beac 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -174,7 +174,12 @@ public class SocketEngine: NSObject, WebSocketDelegate { } private func doFastUpgrade() { - self.sendWebSocketMessage("", withType: PacketType.UPGRADE) + if self.waitingForPoll { + NSLog("Outstanding poll when switched to websockets," + + "we'll probably disconnect soon. You should report this.") + } + + self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil) self._websocket = true self._polling = false self.fastUpgrade = false @@ -207,6 +212,8 @@ public class SocketEngine: NSObject, WebSocketDelegate { } else if err != nil { if self!.polling { self?.handlePollingFailed(err.localizedDescription) + } else { + NSLog(err.localizedDescription) } return @@ -222,11 +229,10 @@ public class SocketEngine: NSObject, WebSocketDelegate { } self?.waitingForPoll = false - if self!.fastUpgrade { self?.doFastUpgrade() return - } else if !self!.closed && !self!.websocket { + } else if !self!.closed && self!.polling { self?.doPoll() } }.resume() @@ -291,14 +297,14 @@ public class SocketEngine: NSObject, WebSocketDelegate { } else if err != nil && self!.polling { self?.handlePollingFailed(err.localizedDescription) return + } else if err != nil { + NSLog(err.localizedDescription) + return } self?.waitingForPost = false dispatch_async(self!.emitQueue) { - if self!.fastUpgrade { - self?.doFastUpgrade() - return - } else { + if !self!.fastUpgrade { self?.flushWaitingForPost() self?.doPoll() } @@ -611,6 +617,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { if self.websocketConnected { // NSLog("Doing fast upgrade") // Do a fast upgrade + // At this point, we should not send anymore polling messages- self.fastUpgrade = true self.sendPollMessage("", withType: PacketType.NOOP) } From eb9d2bc74442551bee1b270635d428792824f2a3 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 6 Apr 2015 12:59:39 -0400 Subject: [PATCH 4/5] better closing --- SwiftIO/SocketEngine.swift | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index ff0beac..3b93fe8 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -104,8 +104,6 @@ public class SocketEngine: NSObject, WebSocketDelegate { if fast || self.polling { self.client?.didForceClose("Disconnect") } - - self.client = nil } private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) { @@ -658,6 +656,11 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.websocketConnected = false self.probing = false + if self.closed { + self.client?.didForceClose("Disconnect") + return + } + if self.websocket { self.pingTimer?.invalidate() self._connected = false From c2d488e35cafcd88b5b946bd604cb59185760577 Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 6 Apr 2015 13:00:16 -0400 Subject: [PATCH 5/5] bump version --- Socket.IO-Client-Swift.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Socket.IO-Client-Swift.podspec b/Socket.IO-Client-Swift.podspec index 1c2d309..9086555 100644 --- a/Socket.IO-Client-Swift.podspec +++ b/Socket.IO-Client-Swift.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Socket.IO-Client-Swift" - s.version = "1.5.0" + s.version = "1.5.1" s.summary = "Socket.IO-client for Swift" s.description = <<-DESC Socket.IO-client for Swift. @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.author = { "Erik" => "nuclear.ace@gmail.com" } s.ios.deployment_target = '8.0' s.osx.deployment_target = '10.10' - s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.5.0' } + s.source = { :git => "https://github.com/socketio/socket.io-client-swift.git", :tag => 'v1.5.1' } s.source_files = "SwiftIO/**/*.swift" s.requires_arc = true # s.dependency 'Starscream', '~> 0.9' # currently this repo includes Starscream swift files