diff --git a/SocketIOClientSwift/SocketEngine.swift b/SocketIOClientSwift/SocketEngine.swift index b66c0dc..87b562d 100644 --- a/SocketIOClientSwift/SocketEngine.swift +++ b/SocketIOClientSwift/SocketEngine.swift @@ -30,7 +30,7 @@ extension String { } } -public final class SocketEngine: NSObject, WebSocketDelegate { +public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient { private typealias Probe = (msg:String, type:PacketType, data:ContiguousArray?) private typealias ProbeWaitQueue = [Probe] @@ -62,6 +62,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { weak var client:SocketEngineClient? var cookies:[NSHTTPCookie]? + var log = false var pingInterval:Int? var polling:Bool { return self._polling @@ -93,11 +94,12 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } public init(client:SocketEngineClient, forcePolling:Bool, - forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?) { + forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?, logging:Bool) { self.client = client self.forcePolling = forcePolling self.forceWebsockets = forceWebsockets self.cookies = cookies + self.log = logging self.session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(), delegate: nil, delegateQueue: self.workQueue) } @@ -181,8 +183,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { private func doFastUpgrade() { if self.waitingForPoll { - NSLog("Outstanding poll when switched to websockets," + - "we'll probably disconnect soon. You should report this.") + SocketLogger.err("Engine: Outstanding poll when switched to WebSockets," + + "we'll probably disconnect soon. You should report this.", client: self) } self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil) @@ -211,7 +213,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData - // NSLog("Doing request: \(req)") + SocketLogger.log("Engine: Doing polling request: \(req)", client: self) + self.session.dataTaskWithRequest(req) {[weak self] data, res, err in if self == nil { return @@ -225,7 +228,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { return } - // NSLog("Got response: \(res)") + SocketLogger.log("Engine: Got polling response: \(res)", client: self!) if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String { dispatch_async(self!.parseQueue) { @@ -245,7 +248,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } private func flushProbeWait() { - // NSLog("flushing probe wait") + SocketLogger.log("Engine: Flushing probe wait", client: self) + dispatch_async(self.emitQueue) {[weak self] in if self == nil { return @@ -294,8 +298,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate { self.waitingForPost = true - // NSLog("posting: \(postStr)") - // NSLog("Posting with WS status of: \(self.websocket)") + SocketLogger.log("Engine: POSTing: \(postStr)", client: self) self.session.dataTaskWithRequest(req) {[weak self] data, res, err in if self == nil { @@ -349,6 +352,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { public func open(opts:[String: AnyObject]? = nil) { if self.connected { + SocketLogger.err("Engine: Tried to open while connected", client: self) + self.client?.didError("Engine tried to open while connected") return } @@ -405,7 +410,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { length += chr } else { if length == "" || testLength(length, &n) { - NSLog("parsing error: \(str)") + SocketLogger.err("Engine: parsing error: \(str)", client: self) + self.handlePollingFailed("Error parsing XHR message") return } @@ -443,7 +449,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } private func parseEngineMessage(var message:String, fromPolling:Bool) { - // NSLog("Engine got message: \(message)") + SocketLogger.log("Engine: Got message: \(message)", client: self) + if fromPolling { fixDoubleUTF8(&message) } @@ -555,7 +562,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { /// Only call on emitQueue private func sendPollMessage(var msg:String, withType type:PacketType, datas:ContiguousArray? = nil) { - // println("Sending poll: \(msg) as type: \(type.rawValue)") + SocketLogger.log("Engine: Sending poll: \(msg) as type: \(type.rawValue)", client: self) + doubleEncodeUTF8(&msg) let strMsg = "\(type.rawValue)\(msg)" @@ -578,7 +586,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { /// Only call on emitQueue private func sendWebSocketMessage(str:String, withType type:PacketType, datas:ContiguousArray? = nil) { - // println("Sending ws: \(str) as type: \(type.rawValue)") + SocketLogger.log("Engine: Sending ws: \(str) as type: \(type.rawValue)", client: self) + self.ws?.writeString("\(type.rawValue)\(str)") if datas != nil { @@ -607,7 +616,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate { private func upgradeTransport() { if self.websocketConnected { - // NSLog("Doing fast upgrade") + SocketLogger.log("Engine: Upgrading transport to WebSockets", client: self) + // Do a fast upgrade // At this point, we should not send anymore polling messages- self.fastUpgrade = true @@ -622,10 +632,10 @@ public final class SocketEngine: NSObject, WebSocketDelegate { } if self!.websocket { - // NSLog("writing ws: \(msg):\(data)") + SocketLogger.log("Engine: Writing ws: \(msg):\(data)", client: self!) self?.sendWebSocketMessage(msg, withType: type, datas: data) } else { - // NSLog("writing poll: \(msg):\(data)") + SocketLogger.log("Engine: Writing poll: \(msg):\(data)", client: self!) self?.sendPollMessage(msg, withType: type, datas: data) } } diff --git a/SocketIOClientSwift/SocketEventHandler.swift b/SocketIOClientSwift/SocketEventHandler.swift index 3a2a75a..16fb228 100644 --- a/SocketIOClientSwift/SocketEventHandler.swift +++ b/SocketIOClientSwift/SocketEventHandler.swift @@ -30,7 +30,7 @@ private func emitAckCallback(socket:SocketIOClient, num:Int) socket.emitAck(num, withData: items) } -class SocketEventHandler { +final class SocketEventHandler { let event:String! let callback:NormalCallback? diff --git a/SocketIOClientSwift/SocketIOClient.swift b/SocketIOClientSwift/SocketIOClient.swift index 5b83603..c708fb8 100644 --- a/SocketIOClientSwift/SocketIOClient.swift +++ b/SocketIOClientSwift/SocketIOClient.swift @@ -24,7 +24,7 @@ import Foundation -public final class SocketIOClient: NSObject, SocketEngineClient { +public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient { private lazy var params = [String: AnyObject]() private var anyHandler:((SocketAnyEvent) -> Void)? private var _closed = false @@ -43,6 +43,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient { let reconnectAttempts:Int! var ackHandlers = SocketAckMap() var currentAck = -1 + var log = false var waitingData = ContiguousArray() public let socketURL:String @@ -92,12 +93,12 @@ public final class SocketIOClient: NSObject, SocketEngineClient { self.cookies = cookies } - if let polling = opts!["forcePolling"] as? Bool { - self.forcePolling = polling + if let log = opts!["log"] as? Bool { + self.log = log } - if let ws = opts!["forceWebsockets"] as? Bool { - self.forceWebsockets = ws + if let polling = opts!["forcePolling"] as? Bool { + self.forcePolling = polling } if var nsp = opts!["nsp"] as? String { @@ -121,6 +122,10 @@ public final class SocketIOClient: NSObject, SocketEngineClient { if let reconnectWait = opts!["reconnectWait"] as? Int { self.reconnectWait = abs(reconnectWait) } + + if let ws = opts!["forceWebsockets"] as? Bool { + self.forceWebsockets = ws + } } else { self.reconnectAttempts = -1 } @@ -133,10 +138,13 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } private func addEngine() { + SocketLogger.log("Client: Adding engine", client: self) + self.engine = SocketEngine(client: self, forcePolling: self.forcePolling, forceWebsockets: self.forceWebsockets, - withCookies: self.cookies) + withCookies: self.cookies, + logging: self.log) } /** @@ -145,6 +153,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { Pass true to fast if you're closing from a background task */ public func close(#fast:Bool) { + SocketLogger.log("Client: Closing socket", client: self) + self.reconnects = false self._connecting = false self._connected = false @@ -212,6 +222,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } func didConnect() { + SocketLogger.log("Client: Socket connected", client: self) + self._closed = false self._connected = true self._connecting = false @@ -228,6 +240,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { /// error public func didError(reason:AnyObject) { + SocketLogger.err("Client: Error", client: self) + self.handleEvent("error", data: reason as? [AnyObject] ?? [reason], isInternalMessage: true) } @@ -299,6 +313,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { SocketParser.parseForEmit(packet) str = packet.createMessageForEvent(event) + SocketLogger.log("Client: Emitting: \(str)", client: self) + if packet.type == SocketPacket.PacketType.BINARY_EVENT { self.engine?.send(str, withData: packet.binary) } else { @@ -319,6 +335,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { SocketParser.parseForEmit(packet) str = packet.createAck() + SocketLogger.log("Client: Emitting: \(str)", client: self!) + if packet.type == SocketPacket.PacketType.BINARY_ACK { self?.engine?.send(str, withData: packet.binary) } else { @@ -333,6 +351,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { return } + SocketLogger.log("Client: Engine closed", client: self) + self._closed = true self._connected = false self.reconnects = false @@ -343,6 +363,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { // Called when the socket gets an ack for something it sent func handleAck(ack:Int, data:AnyObject?) { + SocketLogger.log("Client: Handling ack: \(ack) with data: \(data)", client: self) + self.ackHandlers.executeAck(ack, items: data as? [AnyObject]? ?? data != nil ? [data!] : nil) } @@ -357,6 +379,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { return } + SocketLogger.log("Client: Got event: \(event) with data: \(data)", client: self) + if self.anyHandler != nil { dispatch_async(dispatch_get_main_queue()) {[weak self] in self?.anyHandler?(SocketAnyEvent(event: event, items: data)) @@ -375,6 +399,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } func joinNamespace() { + SocketLogger.log("Client: Joining namespace", client: self) + if self.nsp != "/" { self.engine?.send("0/\(self.nsp)", withData: nil) } @@ -384,6 +410,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { Removes handler(s) */ public func off(event:String) { + SocketLogger.log("Client: Removing handler for event: \(event)", client: self) + self.handlers = self.handlers.filter {$0.event == event ? false : true} } @@ -391,6 +419,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { Adds a handler for an event. */ public func on(name:String, callback:NormalCallback) { + SocketLogger.log("Client: Adding handler for event: \(name)", client: self) + let handler = SocketEventHandler(event: name, callback: callback) self.handlers.append(handler) } @@ -438,6 +468,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } if self.reconnectTimer == nil { + SocketLogger.log("Client: Starting reconnect", client: self) + self._reconnecting = true dispatch_async(dispatch_get_main_queue()) {[weak self] in @@ -451,6 +483,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient { } } + SocketLogger.log("Client: Trying to reconnect", client: self) self.handleEvent("reconnectAttempt", data: [self.reconnectAttempts - self.currentReconnectAttempt], isInternalMessage: true) diff --git a/SocketIOClientSwift/SocketLogger.swift b/SocketIOClientSwift/SocketLogger.swift new file mode 100644 index 0000000..d9531e5 --- /dev/null +++ b/SocketIOClientSwift/SocketLogger.swift @@ -0,0 +1,43 @@ +// +// SocketLogger.swift +// SocketIO-Swift +// +// Created by Erik Little on 4/11/15. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +import Foundation + +protocol SocketLogClient { + var log:Bool {get set} +} + +final class SocketLogger { + static func log(message:String, client:SocketLogClient) { + if client.log { + NSLog("%@", message) + } + } + + static func err(message:String, client:SocketLogClient) { + if client.log { + NSLog("ERROR %@", message) + } + } +} diff --git a/SocketIOClientSwift/SocketPacket.swift b/SocketIOClientSwift/SocketPacket.swift index bc7a126..a53f0e8 100644 --- a/SocketIOClientSwift/SocketPacket.swift +++ b/SocketIOClientSwift/SocketPacket.swift @@ -24,10 +24,16 @@ import Foundation -final class SocketPacket { +final class SocketPacket: Printable { var binary = ContiguousArray() var currentPlace = 0 var data:[AnyObject]? + var description:String { + var ret = "{SocketPacket\n\ttype: \(self.type?.rawValue)\n\tdata: \(self.data)\n\t" + + "id: \(self.id)\n\tplaceholders: \(self.placeholders)" + + return ret + } var id:Int? var justAck = false var nsp = "" diff --git a/SocketIOClientSwift/SocketParser.swift b/SocketIOClientSwift/SocketParser.swift index 822467f..48333e4 100644 --- a/SocketIOClientSwift/SocketParser.swift +++ b/SocketIOClientSwift/SocketParser.swift @@ -194,6 +194,8 @@ class SocketParser { return } + SocketLogger.log("Parser: Decoded packet as: \(p)", client: socket) + if p.type == SocketPacket.PacketType.EVENT { if checkNSP(p.nsp) { return