diff --git a/SwiftIO/SocketEngine.swift b/SwiftIO/SocketEngine.swift index 26a110d..2fd9e2d 100644 --- a/SwiftIO/SocketEngine.swift +++ b/SwiftIO/SocketEngine.swift @@ -47,11 +47,11 @@ public class SocketEngine: NSObject, WebSocketDelegate { unowned let client:SocketEngineClient private let workQueue = NSOperationQueue() private let emitQueue = dispatch_queue_create( - "emitQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) + "engineEmitQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) private let parseQueue = dispatch_queue_create( - "parseQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) + "engineParseQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) private let handleQueue = dispatch_queue_create( - "handleQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) + "engineHandleQueue".cStringUsingEncoding(NSUTF8StringEncoding), DISPATCH_QUEUE_SERIAL) private let session:NSURLSession! private var _connected = false private var fastUpgrade = false @@ -91,7 +91,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { func close() { self.pingTimer?.invalidate() - self.send(PacketType.CLOSE.rawValue) + self.send(PacketType.CLOSE.rawValue, withData: nil) } private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) { @@ -271,7 +271,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { } // A poll failed, tell the client about it - private func handlePollingFailed(reason:NSError?) { + private func handlePollingFailed(reason:NSError) { assert(self.polling, "Polling failed when we're not polling") if !self.client.reconnecting { @@ -422,12 +422,6 @@ public class SocketEngine: NSObject, WebSocketDelegate { fixDoubleUTF8(&message) } - // We should upgrade - if message == "3probe" { - self.upgradeTransport() - return - } - let type = message["^(\\d)"].groups()?[1] if type != PacketType.MESSAGE.rawValue { @@ -452,7 +446,11 @@ public class SocketEngine: NSObject, WebSocketDelegate { self.doPoll() return } else if type == PacketType.PONG.rawValue { - return + // We should upgrade + if message == "3probe" { + self.upgradeTransport() + return + } } if message == PacketType.CLOSE.rawValue { @@ -481,7 +479,7 @@ public class SocketEngine: NSObject, WebSocketDelegate { /* Send a message with type 4 */ - public func send(msg:String, datas:[NSData]? = nil) { + public func send(msg:String, withData datas:[NSData]?) { if self.probing { self.probeWait.append((msg, PacketType.MESSAGE, datas)) } else { diff --git a/SwiftIO/SocketEngineClient.swift b/SwiftIO/SocketEngineClient.swift index 22e2aab..8e984c7 100644 --- a/SwiftIO/SocketEngineClient.swift +++ b/SwiftIO/SocketEngineClient.swift @@ -35,7 +35,7 @@ import Foundation func parseSocketMessage(msg:String) func parseBinaryData(data:NSData) - func pollingDidFail(err:NSError?) + func pollingDidFail(err:NSError) func webSocketDidCloseWithCode(code:Int, reason:String, wasClean:Bool) func webSocketDidFailWithError(error:NSError) -} \ No newline at end of file +} diff --git a/SwiftIO/SocketIOClient.swift b/SwiftIO/SocketIOClient.swift index 56c37e6..425d949 100644 --- a/SwiftIO/SocketIOClient.swift +++ b/SwiftIO/SocketIOClient.swift @@ -42,7 +42,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { private var reconnectTimer:NSTimer? internal var currentAck = -1 - internal var waitingData = [SocketEvent]() + internal var waitingData = [SocketPacket]() public let socketURL:String public let ackQueue = dispatch_queue_create("ackQueue".cStringUsingEncoding(NSUTF8StringEncoding), @@ -190,7 +190,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { self.reconnects = false self._connecting = false self._reconnecting = false - self.handleEvent("disconnect", data: message, isInternalMessage: true) + self.handleEvent("disconnect", data: [message], isInternalMessage: true) } /** @@ -244,7 +244,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { } private func _emit(event:String, _ args:[AnyObject], ack:Int? = nil) { - var frame:SocketEvent + var frame:SocketPacket var str:String let (items, hasBinary, emitDatas) = SocketParser.parseEmitArgs(args) @@ -255,24 +255,24 @@ public class SocketIOClient: NSObject, SocketEngineClient { if hasBinary { if ack == nil { - str = SocketEvent.createMessageForEvent(event, withArgs: items, + str = SocketPacket.createMessageForEvent(event, withArgs: items, hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp) } else { - str = SocketEvent.createMessageForEvent(event, withArgs: items, + str = SocketPacket.createMessageForEvent(event, withArgs: items, hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp, wantsAck: ack) } - self.engine?.send(str, datas: emitDatas) + self.engine?.send(str, withData: emitDatas) } else { if ack == nil { - str = SocketEvent.createMessageForEvent(event, withArgs: items, hasBinary: false, + str = SocketPacket.createMessageForEvent(event, withArgs: items, hasBinary: false, withDatas: 0, toNamespace: self.nsp) } else { - str = SocketEvent.createMessageForEvent(event, withArgs: items, hasBinary: false, + str = SocketPacket.createMessageForEvent(event, withArgs: items, hasBinary: false, withDatas: 0, toNamespace: self.nsp, wantsAck: ack) } - self.engine?.send(str) + self.engine?.send(str, withData: nil) } } @@ -289,24 +289,24 @@ public class SocketIOClient: NSObject, SocketEngineClient { if !hasBinary { if self?.nsp == nil { - str = SocketEvent.createAck(ack, withArgs: items, + str = SocketPacket.createAck(ack, withArgs: items, withAckType: 3, withNsp: "/") } else { - str = SocketEvent.createAck(ack, withArgs: items, + str = SocketPacket.createAck(ack, withArgs: items, withAckType: 3, withNsp: self!.nsp!) } - self?.engine?.send(str) + self?.engine?.send(str, withData: nil) } else { if self?.nsp == nil { - str = SocketEvent.createAck(ack, withArgs: items, + str = SocketPacket.createAck(ack, withArgs: items, withAckType: 6, withNsp: "/", withBinary: emitDatas.count) } else { - str = SocketEvent.createAck(ack, withArgs: items, + str = SocketPacket.createAck(ack, withArgs: items, withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count) } - self?.engine?.send(str, datas: emitDatas) + self?.engine?.send(str, withData: emitDatas) } } } @@ -333,7 +333,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { /** Causes an event to be handled. Only use if you know what you're doing. */ - public func handleEvent(event:String, data:AnyObject?, isInternalMessage:Bool = false, + public func handleEvent(event:String, data:[AnyObject]?, isInternalMessage:Bool = false, wantsAck ack:Int? = nil, withAckType ackType:Int = 3) { // println("Should do event: \(event) with data: \(data)") if !self.connected && !isInternalMessage { @@ -349,29 +349,11 @@ public class SocketIOClient: NSObject, SocketEngineClient { for handler in self.handlers { if handler.event == event { - if data is NSArray { - if ack != nil { - handler.executeCallback(data as? NSArray, withAck: ack!, - withAckType: ackType, withSocket: self) - } else { - handler.executeCallback(data as? NSArray) - } + if ack != nil { + handler.executeCallback(data, withAck: ack!, + withAckType: ackType, withSocket: self) } else { - - // Trying to do a ternary expression in the executeCallback method - // seemed to crash Swift - var dataArr:NSArray? = nil - - if let data:AnyObject = data { - dataArr = [data] - } - - if ack != nil { - handler.executeCallback(dataArr, withAck: ack!, - withAckType: ackType, withSocket: self) - } else { - handler.executeCallback(dataArr) - } + handler.executeCallback(data) } } } @@ -380,7 +362,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { // Should be removed and moved to SocketEngine func joinNamespace() { if self.nsp != nil { - self.engine?.send("0/\(self.nsp!)") + self.engine?.send("0/\(self.nsp!)", withData: nil) } } @@ -415,10 +397,10 @@ public class SocketIOClient: NSObject, SocketEngineClient { } // Something happened while polling - public func pollingDidFail(err:NSError?) { + public func pollingDidFail(err:NSError) { if !self.reconnecting { self._connected = false - self.handleEvent("reconnect", data: err?.localizedDescription, isInternalMessage: true) + self.handleEvent("reconnect", data: [err.localizedDescription], isInternalMessage: true) self.tryReconnect() } } @@ -452,7 +434,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { } } - self.handleEvent("reconnectAttempt", data: self.reconnectAttempts - self.currentReconnectAttempt, + self.handleEvent("reconnectAttempt", data: [self.reconnectAttempts - self.currentReconnectAttempt], isInternalMessage: true) self.currentReconnectAttempt++ @@ -470,7 +452,7 @@ public class SocketIOClient: NSObject, SocketEngineClient { if self.closed || !self.reconnects { self.didForceClose(message: "WebSocket closed") } else { - self.handleEvent("reconnect", data: reason, isInternalMessage: true) + self.handleEvent("reconnect", data: [reason], isInternalMessage: true) self.tryReconnect() } } @@ -479,11 +461,11 @@ public class SocketIOClient: NSObject, SocketEngineClient { public func webSocketDidFailWithError(error:NSError) { self._connected = false self._connecting = false - self.handleEvent("error", data: error.localizedDescription, isInternalMessage: true) + self.handleEvent("error", data: [error.localizedDescription], isInternalMessage: true) if self.closed || !self.reconnects { self.didForceClose(message: "WebSocket closed with an error \(error)") } else if !self.reconnecting { - self.handleEvent("reconnect", data: error.localizedDescription, isInternalMessage: true) + self.handleEvent("reconnect", data: [error.localizedDescription], isInternalMessage: true) self.tryReconnect() } } diff --git a/SwiftIO/SocketEvent.swift b/SwiftIO/SocketPacket.swift similarity index 73% rename from SwiftIO/SocketEvent.swift rename to SwiftIO/SocketPacket.swift index 48660c7..56668f3 100644 --- a/SwiftIO/SocketEvent.swift +++ b/SwiftIO/SocketPacket.swift @@ -1,5 +1,5 @@ // -// Event.swift +// SocketPacket.swift // Socket.IO-Swift // // Created by Erik Little on 1/18/15. @@ -24,23 +24,53 @@ import Foundation -class SocketEvent { - let justAck:Bool! - var ack:Int? - var args:AnyObject! - lazy var currentPlace = 0 - lazy var datas = [NSData]() - var event:String! - var placeholders:Int! - - init(event:String, args:AnyObject?, placeholders:Int = 0, ackNum:Int? = nil, justAck:Bool = false) { - self.event = event - self.args = args - self.placeholders = placeholders - self.ack = ackNum - self.justAck = justAck +enum SocketPacketType: Int { + case CONNECT = 0 + case DISCONNECT = 1 + case EVENT = 2 + case ACK = 3 + case ERROR = 4 + case BINARY_EVENT = 5 + case BINARY_ACK = 6 + + init(str:String) { + if let int = str.toInt() { + self = SocketPacketType(rawValue: int)! + } else { + self = SocketPacketType(rawValue: 4)! + } } - +} + +class SocketPacket { + let type:SocketPacketType + var binary = [NSData]() + var currentPlace = 0 + var data:[AnyObject]? + var id:Int? + var justAck = false + var nsp = "" + var placeholders:Int? + + init(type:SocketPacketType, data:[AnyObject]? = nil, nsp:String = "", + placeholders:Int? = nil, id:Int? = nil) { + self.type = type + self.data = data + self.nsp = nsp + self.placeholders = placeholders + self.id = id + } + + /// Only call if you know data is not nil + func createBinaryPlaceHolders() { + var strData = "\(self.data!)" + println(strData) + } + + func getEvent() -> String { + return data?.removeAtIndex(0) as String + } + func addData(data:NSData) -> Bool { func checkDoEvent() -> Bool { if self.placeholders == self.currentPlace { @@ -49,14 +79,14 @@ class SocketEvent { return false } } - + if checkDoEvent() { return true } - - self.datas.append(data) + + self.binary.append(data) self.currentPlace++ - + if checkDoEvent() { self.currentPlace = 0 return true @@ -64,13 +94,13 @@ class SocketEvent { return false } } - + class func createMessageForEvent(event:String, withArgs args:[AnyObject], hasBinary:Bool, withDatas datas:Int = 0, toNamespace nsp:String?, wantsAck ack:Int? = nil) -> String { - + var message:String var jsonSendError:NSError? - + if !hasBinary { if nsp == nil { if ack == nil { @@ -100,14 +130,14 @@ class SocketEvent { } } } - + return self.completeMessage(message, args: args) } - + class func createAck(ack:Int, withArgs args:[AnyObject], withAckType ackType:Int, withNsp nsp:String, withBinary binary:Int = 0) -> String { var msg:String - + if ackType == 3 { if nsp == "/" { msg = "3\(ack)[" @@ -121,52 +151,52 @@ class SocketEvent { msg = "6\(binary)-/\(nsp),\(ack)[" } } - + return self.completeMessage(msg, args: args, ack: true) } - + private class func completeMessage(var message:String, args:[AnyObject], ack:Bool = false) -> String { var err:NSError? - + if args.count == 0 { return message + "]" } else if !ack { message += "," } - + for arg in args { - + if arg is NSDictionary || arg is [AnyObject] { let jsonSend = NSJSONSerialization.dataWithJSONObject(arg, options: NSJSONWritingOptions(0), error: &err) let jsonString = NSString(data: jsonSend!, encoding: NSUTF8StringEncoding) - + message += jsonString! as String message += "," continue } - + if arg is String { message += "\"\(arg)\"" message += "," continue } - + message += "\(arg)" message += "," } - + if message != "" { message.removeAtIndex(message.endIndex.predecessor()) } - + return message + "]" } - + private func fillInArray(arr:NSArray) -> NSArray { var newArr = [AnyObject](count: arr.count, repeatedValue: 0) // println(arr) - + for i in 0.. NSDictionary { var newDict = [String: AnyObject]() - + for (key, value) in dict { newDict[key as! String] = value - + // If the value is a string we need to check // if it is a placeholder for data if let str = value as? String { @@ -206,45 +236,29 @@ class SocketEvent { newDict[key as! String] = self.fillInArray(arr) } } - + return newDict } - - func fillInPlaceholders(_ args:AnyObject = true) -> AnyObject { - if let dict = args as? NSDictionary { - return self.fillInDict(dict) - } else if let arr = args as? NSArray { - return self.fillInArray(args as! NSArray) - } else if let string = args as? String { - if string == "~~\(self.currentPlace)" { - return self.datas[0] - } - } else if args is Bool { - // We have multiple items - // Do it live - let argsAsArray = "[\(self.args)]" - if let parsedArr = SocketParser.parseData(argsAsArray) as? NSArray { - var returnArr = [AnyObject](count: parsedArr.count, repeatedValue: 0) - - for i in 0.. SocketPacket? { + let arr = Array(str) + let type = String(arr[0]) + + if arr.count == 1 { + return SocketPacket(type: SocketPacketType(str: type)) + } + + var id = nil as Int? + var nsp = "" + var i = 0 + var placeholders = -1 + + if type == "5" || type == "6" { + var buf = "" + + while arr[++i] != "-" { + buf += String(arr[i]) + if i == arr.count { + break + } + } + + if buf.toInt() == nil || arr[i] != "-" { + println(buf) + NSLog("Error parsing \(str)") + return nil + } else { + placeholders = buf.toInt()! + } + } + + if arr[i + 1] == "/" { + while ++i < arr.count { + let c = arr[i] + + if c == "," { + break + } + + nsp += String(c) + } + } + + if i + 1 >= arr.count { + return SocketPacket(type: SocketPacketType(str: type), + nsp: nsp, placeholders: placeholders, id: id) + } + + let next = String(arr[i + 1]) + + if next.toInt() != nil { + var c = "" + while ++i < arr.count { + if let int = String(arr[i]).toInt() { + c += String(arr[i]) + } else { + --i + break + } + } + + id = c.toInt() + } + + if i + 1 < arr.count { + let d = String(arr[++i...arr.count-1]) + let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" + + let data = SocketParser.parseData(noPlaceholders) as [AnyObject] + + return SocketPacket(type: SocketPacketType(str: type), data: data, + nsp: nsp, placeholders: placeholders, id: id) + } + + return nil + } + // Parse an NSArray looking for binary data class func parseArray(arr:NSArray, var currentPlaceholder:Int) -> (NSArray, Bool, [NSData]) { var replacementArr = [AnyObject](count: arr.count, repeatedValue: 1) @@ -72,13 +151,9 @@ class SocketParser { } // Parses data for events - class func parseData(data:String?) -> AnyObject? { - if data == nil { - return nil - } - + class func parseData(data:String) -> AnyObject? { var err:NSError? - let stringData = data!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) + let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!, options: NSJSONReadingOptions.AllowFragments, error: &err) @@ -190,76 +265,52 @@ class SocketParser { return } - // NSLog(stringMessage) - - // Check for successful namepsace connect - if socket.nsp != nil { - if stringMessage == "0/\(socket.nsp!)" { - socket.didConnect() - return + func checkNSP(nsp:String) -> Bool { + if nsp == "" && socket.nsp != nil { + return true + } else { + return false } } - if stringMessage == "0" { - if socket.nsp != nil { - // Join namespace - socket.joinNamespace() + var p = parseString(stringMessage) as SocketPacket! + + + if p.type == SocketPacketType.EVENT { + if checkNSP(p.nsp) { return + } + + socket.handleEvent(p.getEvent(), data: p.data, isInternalMessage: false, wantsAck: p.id, withAckType: 3) + } else if p.type == SocketPacketType.ACK { + if checkNSP(p.nsp) { + return + } + + socket.handleAck(p.id!, data: p.data) + } else if p.type == SocketPacketType.BINARY_EVENT { + if checkNSP(p.nsp) { + return + } + + socket.waitingData.append(p) + } else if p.type == SocketPacketType.BINARY_ACK { + if checkNSP(p.nsp) { + return + } + + p.justAck = true + socket.waitingData.append(p) + } else if p.type == SocketPacketType.CONNECT { + if p.nsp == "" && socket.nsp != nil { + socket.joinNamespace() + } else if p.nsp != "" && socket.nsp == nil { + socket.didConnect() } else { socket.didConnect() - return } - } else if stringMessage == "1" { - socket.didForceClose(message: "Got disconnect") - return - } - - if stringMessage.hasPrefix("5") || stringMessage.hasPrefix("6") { - // Check for message with binary placeholders - self.parseBinaryMessage(stringMessage, socket: socket) - return - } - - let type = stringMessage.removeAtIndex(stringMessage.startIndex) - - if type == "2" { - if let groups = stringMessage["(\\/(\\w*))?,?(\\d*)?\\[\"(.*?)\",?(.*?)?\\]$", - NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { - let namespace = groups[2] - let ackNum = groups[3] - let event = groups[4] - let data = "[\(groups[5])]" - - if namespace == "" && socket.nsp != nil { - return - } - - if let parsed:AnyObject = self.parseData(data) { - if ackNum == "" { - socket.handleEvent(event, data: parsed) - } else { - socket.currentAck = ackNum.toInt()! - socket.handleEvent(event, data: parsed, isInternalMessage: false, - wantsAck: ackNum.toInt(), withAckType: 3) - } - } - } - } else if type == "3" { - if let ackGroup = stringMessage["(\\/(\\w*))?,?(\\d*)?\\[(.*?)?\\]$", - NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { - let nsp = ackGroup[2] - let ackNum = ackGroup[3] - let ackData:AnyObject? = self.parseData("[\(ackGroup[4])]") - - if nsp == "" && socket.nsp != nil { - return - } - - socket.handleAck(ackNum.toInt()!, data: ackData) - } - } else { - NSLog("Error in parsing message: %s", stringMessage) - return + } else if p.type == SocketPacketType.DISCONNECT { + socket.didForceClose(message: "Got Disconnect") } } @@ -274,103 +325,18 @@ class SocketParser { let shouldExecute = socket.waitingData[0].addData(data) - if shouldExecute { - let socketEvent = socket.waitingData.removeAtIndex(0) - var event = socketEvent.event - var parsedArgs:AnyObject? = self.parseData(socketEvent.args as? String) - - if let args:AnyObject = parsedArgs { - let filledInArgs:AnyObject = socketEvent.fillInPlaceholders(args) - - if socketEvent.justAck! { - // Should handle ack - socket.handleAck(socketEvent.ack!, data: filledInArgs) - return - } - - // Should do event - if socketEvent.ack != nil { - socket.handleEvent(event, data: filledInArgs, isInternalMessage: false, - wantsAck: socketEvent.ack!, withAckType: 6) - } else { - socket.handleEvent(event, data: filledInArgs) - } - } else { - let filledInArgs:AnyObject = socketEvent.fillInPlaceholders() - - // Should handle ack - if socketEvent.justAck! { - socket.handleAck(socketEvent.ack!, data: filledInArgs) - return - } - - // Should handle ack - if socketEvent.ack != nil { - socket.handleEvent(event, data: filledInArgs, isInternalMessage: false, - wantsAck: socketEvent.ack!, withAckType: 6) - } else { - socket.handleEvent(event, data: filledInArgs) - } - } - } - } - - // Tries to parse a message that contains binary - class func parseBinaryMessage(var message:String, socket:SocketIOClient) { - // NSLog(message) - - let type = message.removeAtIndex(message.startIndex) - - if type == "5" { - if let groups = message["^(\\d*)-(\\/(\\w*))?,?(\\d*)?\\[\"(.*?)\",?(.*)?\\]$", - NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { - let numberOfPlaceholders = groups[1] - let namespace = groups[3] - let ackNum = groups[4] - let event = groups[5] - let mutMessageObject = groups[6] - - if namespace == "" && socket.nsp != nil { - return - } - - let placeholdersRemoved = mutMessageObject["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] - ~= "\"~~$2\"" - - var mes:SocketEvent - if ackNum == "" { - mes = SocketEvent(event: event, args: placeholdersRemoved, - placeholders: numberOfPlaceholders.toInt()!) - } else { - socket.currentAck = ackNum.toInt()! - mes = SocketEvent(event: event, args: placeholdersRemoved, - placeholders: numberOfPlaceholders.toInt()!, ackNum: ackNum.toInt()) - } - - socket.waitingData.append(mes) - } - } else if type == "6" { - if let groups = message["^(\\d*)-(\\/(\\w*))?,?(\\d*)?\\[(.*?)?\\]$", - NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { - let numberOfPlaceholders = groups[1] - let namespace = groups[3] - let ackNum = groups[4] - let mutMessageObject = groups[5] - - if namespace == "" && socket.nsp != nil { - return - } - let placeholdersRemoved = mutMessageObject["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] - ~= "\"~~$2\"" - - let event = SocketEvent(event: "", args: placeholdersRemoved, - placeholders: numberOfPlaceholders.toInt()!, ackNum: ackNum.toInt(), justAck: true) - - socket.waitingData.append(event) - } - } else { - NSLog("Error in parsing binary message: %s", message) + if !shouldExecute { return } + + let packet = socket.waitingData.removeAtIndex(0) + packet.fillInPlaceholders() + + if !packet.justAck { + socket.handleEvent(packet.getEvent(), data: packet.data, + wantsAck: packet.id, withAckType: 6) + } else { + socket.handleAck(packet.id!, data: packet.data) + } } }