merge master
This commit is contained in:
commit
504d0fbd18
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@ -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..<arr.count {
|
||||
if let nest = arr[i] as? NSArray {
|
||||
newArr[i] = self.fillInArray(nest)
|
||||
@ -174,7 +204,7 @@ class SocketEvent {
|
||||
newArr[i] = self.fillInDict(dict)
|
||||
} else if let str = arr[i] as? String {
|
||||
if let num = str["~~(\\d)"].groups() {
|
||||
newArr[i] = self.datas[num[1].toInt()!]
|
||||
newArr[i] = self.binary[num[1].toInt()!]
|
||||
} else {
|
||||
newArr[i] = arr[i]
|
||||
}
|
||||
@ -182,16 +212,16 @@ class SocketEvent {
|
||||
newArr[i] = arr[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return newArr
|
||||
}
|
||||
|
||||
|
||||
private func fillInDict(dict:NSDictionary) -> 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..<parsedArr.count {
|
||||
if let str = parsedArr[i] as? String {
|
||||
if let num = str["~~(\\d)"].groups() {
|
||||
returnArr[i] = self.datas[num[1].toInt()!]
|
||||
} else {
|
||||
returnArr[i] = str
|
||||
}
|
||||
} else if let arr = parsedArr[i] as? NSArray {
|
||||
returnArr[i] = self.fillInArray(arr)
|
||||
} else if let dict = parsedArr[i] as? NSDictionary {
|
||||
returnArr[i] = self.fillInDict(dict)
|
||||
} else {
|
||||
returnArr[i] = parsedArr[i]
|
||||
}
|
||||
|
||||
func fillInPlaceholders() {
|
||||
var newArr = [AnyObject](count: self.data!.count, repeatedValue: 0)
|
||||
|
||||
for i in 0..<self.data!.count {
|
||||
if let str = self.data?[i] as? String {
|
||||
if let num = str["~~(\\d)"].groups() {
|
||||
newArr[i] = self.binary[num[1].toInt()!]
|
||||
} else {
|
||||
newArr[i] = str
|
||||
}
|
||||
return returnArr
|
||||
} else if let arr = self.data?[i] as? NSArray {
|
||||
newArr[i] = self.fillInArray(arr)
|
||||
} else if let dict = self.data?[i] as? NSDictionary {
|
||||
newArr[i] = self.fillInDict(dict)
|
||||
} else {
|
||||
newArr[i] = self.data![i]
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
||||
self.data = newArr
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,85 @@
|
||||
import Foundation
|
||||
|
||||
class SocketParser {
|
||||
// Translation of socket.io-client#decodeString
|
||||
class func parseString(str:String) -> 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user