From 5ed2688c9e657d3fde79dc0dce0f85370bdb20dd Mon Sep 17 00:00:00 2001 From: Erik Date: Thu, 5 Mar 2015 12:55:09 -0500 Subject: [PATCH] better handle when the server closes the connection (polling) --- SwiftIO/SocketEngine.swift | 38 ++++++++++++++++++++++++++--------- SwiftIO/SocketIOClient.swift | 39 +++++++++++++++--------------------- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index 4556848..393cf22 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -85,10 +85,6 @@ class SocketEngine: NSObject, SRWebSocketDelegate { } else { self.client.didForceClose() } - - if self.polling { - self.client.handleEvent("disconnect", data: "close", isInternalMessage: true) - } } private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) { @@ -147,9 +143,8 @@ class SocketEngine: NSObject, SRWebSocketDelegate { return } - let time = Int(NSDate().timeIntervalSince1970) let req = NSURLRequest(URL: - NSURL(string: self.urlPolling! + "&t=\(time)-0&b64=1" + "&sid=\(self.sid)")!) + NSURL(string: self.urlPolling! + "&sid=\(self.sid)")!) self.wait = true NSURLConnection.sendAsynchronousRequest(req, @@ -248,13 +243,38 @@ class SocketEngine: NSObject, SRWebSocketDelegate { } } - // A poll failed, try and reconnect + // A poll failed, tell the client about it + // We check to see if we were closed by the server first private func handlePollingFailed() { if !self.client.reconnecting { self.pingTimer?.invalidate() self.wait = false - self.client.handleEvent("reconnect", data: "XHR polling timeout", isInternalMessage: true) - self.client.tryReconnect(triesLeft: self.client.reconnectAttempts) + + let forced = {() -> Bool in + var err:NSError? + let url = NSURL(string: self.urlPolling! + "&sid=\(self.sid)")! + let req = NSURLRequest(URL: url, cachePolicy: + NSURLRequestCachePolicy.UseProtocolCachePolicy, timeoutInterval: 4) + var resp:NSURLResponse? + let data = NSURLConnection.sendSynchronousRequest(req, returningResponse: &resp, error: &err) + + if data == nil || resp == nil || err != nil { + return false + } else if let str = NSString(data: data!, encoding: NSUTF8StringEncoding) { + if str == "1:61:1" { + return true + } else { + return false + } + } else { + return false + }}() + + if forced { + self.close(forced: true) + } else { + self.client.pollingDidFail() + } } } diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index 8108c1a..9dcc88b 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -119,14 +119,17 @@ class SocketIOClient { self.connected = true self.connecting = false self.reconnecting = false + self.handleEvent("connect", data: nil, isInternalMessage: false) } // Server wants us to die func didForceClose() { self.closed = true - self.connecting = false self.connected = false + self.reconnects = false + self.connecting = false self.reconnecting = false + self.handleEvent("disconnect", data: "closed", isInternalMessage: true) } // Sends a message with multiple args @@ -489,7 +492,6 @@ class SocketIOClient { if self.nsp != nil { if stringMessage == "0/\(self.nsp!)" { self.didConnect() - self.handleEvent("connect", data: nil) return } } @@ -503,7 +505,6 @@ class SocketIOClient { // Don't handle as internal because something crazy could happen where // we disconnect before it's handled self.didConnect() - self.handleEvent("connect", data: nil) return } } @@ -758,16 +759,20 @@ class SocketIOClient { } } + // Something happened while polling + func pollingDidFail() { + if !self.reconnecting { + self.handleEvent("reconnect", data: "XHR polling error", isInternalMessage: true) + self.tryReconnect(triesLeft: self.reconnectAttempts) + } + } + // We lost connection and should attempt to reestablish func tryReconnect(var #triesLeft:Int) { self.connected = false if triesLeft != -1 && triesLeft <= 0 { - self.connected = false - self.connecting = false - self.reconnects = false - self.reconnecting = false - self.handleEvent("disconnect", data: "Failed to reconnect", isInternalMessage: true) + self.didForceClose() return } else if self.connected { self.connecting = false @@ -776,7 +781,7 @@ class SocketIOClient { } // println("Trying to reconnect #\(reconnectAttempts - triesLeft)") - self.handleEvent("reconnectAttempt", data: triesLeft, isInternalMessage: true) + self.handleEvent("reconnectAttempt", data: triesLeft - 1, isInternalMessage: true) let waitTime = UInt64(self.reconnectWait) * NSEC_PER_SEC let time = dispatch_time(DISPATCH_TIME_NOW, Int64(waitTime)) @@ -802,27 +807,15 @@ class SocketIOClient { } } - // Called when a message is recieved - func webSocket(webSocket:SRWebSocket!, didReceiveMessage message:AnyObject?) { - dispatch_async(self.handleQueue) {[weak self] in - if self == nil { - return - } - - self?.parseSocketMessage(message) - } - } - // Called when the socket is closed func webSocketDidCloseWithCode(code:Int, reason:String!, wasClean:Bool) { self.connected = false self.connecting = false if self.closed || !self.reconnects { - self.handleEvent("disconnect", data: reason, isInternalMessage: true) + self.didForceClose() } else { self.handleEvent("reconnect", data: reason, isInternalMessage: true) self.tryReconnect(triesLeft: self.reconnectAttempts) - } } @@ -832,7 +825,7 @@ class SocketIOClient { self.connecting = false self.handleEvent("error", data: error.localizedDescription, isInternalMessage: true) if self.closed || !self.reconnects { - self.handleEvent("disconnect", data: error.localizedDescription, isInternalMessage: true) + self.didForceClose() } else if !self.reconnecting { self.handleEvent("reconnect", data: error.localizedDescription, isInternalMessage: true) self.tryReconnect(triesLeft: self.reconnectAttempts)