This commit is contained in:
Erik 2015-04-09 01:39:27 -04:00
parent 7adf624dca
commit a9cf6885aa
4 changed files with 71 additions and 61 deletions

View File

@ -349,7 +349,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
public func open(opts:[String: AnyObject]? = nil) { public func open(opts:[String: AnyObject]? = nil) {
if self.connected { if self.connected {
self.client?.engineDidError("Engine tried to open while connected") self.client?.didError("Engine tried to open while connected")
return return
} }
@ -478,9 +478,8 @@ public class SocketEngine: NSObject, WebSocketDelegate {
message.removeAtIndex(message.startIndex) message.removeAtIndex(message.startIndex)
let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
if let json = NSJSONSerialization.JSONObjectWithData(mesData, if let json = NSJSONSerialization.JSONObjectWithData(mesData, options: NSJSONReadingOptions.AllowFragments,
options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary, error: &err) as? NSDictionary, let sid = json["sid"] as? String {
let sid = json["sid"] as? String {
self.sid = sid self.sid = sid
self._connected = true self._connected = true
@ -492,7 +491,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
self.pingInterval = pingInterval / 1000 self.pingInterval = pingInterval / 1000
} }
} else { } else {
self.client?.engineDidError("Engine failed to handshake") self.client?.didError("Engine failed to handshake")
return return
} }

View File

@ -32,7 +32,7 @@ import Foundation
var socketURL:String {get} var socketURL:String {get}
var secure:Bool {get} var secure:Bool {get}
func engineDidError(reason:String) func didError(reason:AnyObject)
func engineDidForceClose(reason:String) func engineDidForceClose(reason:String)
func parseSocketMessage(msg:String) func parseSocketMessage(msg:String)
func parseBinaryData(data:NSData) func parseBinaryData(data:NSData)

View File

@ -226,6 +226,15 @@ public class SocketIOClient: NSObject, SocketEngineClient {
self.handleEvent("connect", data: nil, isInternalMessage: false) self.handleEvent("connect", data: nil, isInternalMessage: false)
} }
/// error
public func didError(reason:AnyObject) {
if !(reason is [AnyObject]) {
self.handleEvent("error", data: [reason], isInternalMessage: true)
} else {
self.handleEvent("error", data: reason as? [AnyObject], isInternalMessage: true)
}
}
/** /**
Same as close Same as close
*/ */
@ -321,11 +330,6 @@ public class SocketIOClient: NSObject, SocketEngineClient {
} }
} }
/// Engine error
public func engineDidError(reason:String) {
self.handleEvent("error", data: [reason], isInternalMessage: true)
}
/// Server wants us to die /// Server wants us to die
public func engineDidForceClose(reason:String) { public func engineDidForceClose(reason:String) {
if self.closed { if self.closed {

View File

@ -24,46 +24,46 @@ import Foundation
class SocketParser { class SocketParser {
private static let shredder = SocketParser.PacketShredder() private static let shredder = SocketParser.PacketShredder()
// Translation of socket.io-parser#deconstructPacket // Translation of socket.io-parser#deconstructPacket
private class PacketShredder { private class PacketShredder {
var buf = ContiguousArray<NSData>() var buf = ContiguousArray<NSData>()
func shred(data:AnyObject) -> AnyObject { func shred(data:AnyObject) -> AnyObject {
if let bin = data as? NSData { if let bin = data as? NSData {
let placeholder = ["_placeholder" :true, "num": buf.count] let placeholder = ["_placeholder" :true, "num": buf.count]
buf.append(bin) buf.append(bin)
return placeholder return placeholder
} else if let arr = data as? NSArray { } else if let arr = data as? NSArray {
var newArr = NSMutableArray(array: arr) var newArr = NSMutableArray(array: arr)
for i in 0..<arr.count { for i in 0..<arr.count {
newArr[i] = shred(arr[i]) newArr[i] = shred(arr[i])
} }
return newArr return newArr
} else if let dict = data as? NSDictionary { } else if let dict = data as? NSDictionary {
var newDict = NSMutableDictionary(dictionary: dict) var newDict = NSMutableDictionary(dictionary: dict)
for (key, value) in newDict { for (key, value) in newDict {
newDict[key as! NSCopying] = shred(value) newDict[key as! NSCopying] = shred(value)
} }
return newDict return newDict
} else { } else {
return data return data
} }
} }
func deconstructPacket(packet:SocketPacket) { func deconstructPacket(packet:SocketPacket) {
if packet.data == nil { if packet.data == nil {
return return
} }
var data = packet.data! var data = packet.data!
for i in 0..<data.count { for i in 0..<data.count {
if data[i] is NSArray || data[i] is NSDictionary { if data[i] is NSArray || data[i] is NSDictionary {
data[i] = shred(data[i]) data[i] = shred(data[i])
@ -72,37 +72,37 @@ class SocketParser {
buf.append(bin) buf.append(bin)
} }
} }
packet.data = data packet.data = data
packet.binary = buf packet.binary = buf
buf.removeAll(keepCapacity: true) buf.removeAll(keepCapacity: true)
} }
} }
// Translation of socket.io-client#decodeString // Translation of socket.io-client#decodeString
static func parseString(str:String) -> SocketPacket? { static func parseString(str:String) -> SocketPacket? {
let arr = Array(str) let arr = Array(str)
let type = String(arr[0]) let type = String(arr[0])
if arr.count == 1 { if arr.count == 1 {
return SocketPacket(type: SocketPacketType(str: type)) return SocketPacket(type: SocketPacketType(str: type))
} }
var id = nil as Int? var id = nil as Int?
var nsp = "" var nsp = ""
var i = 0 var i = 0
var placeholders = -1 var placeholders = -1
if type == "5" || type == "6" { if type == "5" || type == "6" {
var buf = "" var buf = ""
while arr[++i] != "-" { while arr[++i] != "-" {
buf += String(arr[i]) buf += String(arr[i])
if i == arr.count { if i == arr.count {
break break
} }
} }
if buf.toInt() == nil || arr[i] != "-" { if buf.toInt() == nil || arr[i] != "-" {
NSLog("Error parsing \(str)") NSLog("Error parsing \(str)")
return nil return nil
@ -110,26 +110,26 @@ class SocketParser {
placeholders = buf.toInt()! placeholders = buf.toInt()!
} }
} }
if arr[i + 1] == "/" { if arr[i + 1] == "/" {
while ++i < arr.count { while ++i < arr.count {
let c = arr[i] let c = arr[i]
if c == "," { if c == "," {
break break
} }
nsp += String(c) nsp += String(c)
} }
} }
if i + 1 >= arr.count { if i + 1 >= arr.count {
return SocketPacket(type: SocketPacketType(str: type), return SocketPacket(type: SocketPacketType(str: type),
nsp: nsp, placeholders: placeholders, id: id) nsp: nsp, placeholders: placeholders, id: id)
} }
let next = String(arr[i + 1]) let next = String(arr[i + 1])
if next.toInt() != nil { if next.toInt() != nil {
var c = "" var c = ""
while ++i < arr.count { while ++i < arr.count {
@ -140,78 +140,83 @@ class SocketParser {
break break
} }
} }
id = c.toInt() id = c.toInt()
} }
if i + 1 < arr.count { if ++i < arr.count {
let d = String(arr[++i...arr.count-1]) let d = String(arr[i...arr.count-1])
let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\"" let noPlaceholders = d["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] ~= "\"~~$2\""
let data:[AnyObject]
let data = SocketParser.parseData(noPlaceholders) as! [AnyObject]
if let isArr = SocketParser.parseData(noPlaceholders) as? [AnyObject] {
data = isArr
} else {
data = [noPlaceholders]
}
return SocketPacket(type: SocketPacketType(str: type), data: data, return SocketPacket(type: SocketPacketType(str: type), data: data,
nsp: nsp, placeholders: placeholders, id: id) nsp: nsp, placeholders: placeholders, id: id)
} }
return nil return nil
} }
// Parses data for events // Parses data for events
static func parseData(data:String) -> AnyObject? { static func parseData(data:String) -> AnyObject? {
var err:NSError? var err:NSError?
let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) let stringData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!, let parsed:AnyObject? = NSJSONSerialization.JSONObjectWithData(stringData!,
options: NSJSONReadingOptions.AllowFragments, error: &err) options: NSJSONReadingOptions.AllowFragments, error: &err)
if err != nil { if err != nil {
// println(err) // println(err)
return nil return nil
} }
return parsed return parsed
} }
static func parseForEmit(packet:SocketPacket) { static func parseForEmit(packet:SocketPacket) {
shredder.deconstructPacket(packet) shredder.deconstructPacket(packet)
} }
// Parses messages recieved // Parses messages recieved
static func parseSocketMessage(stringMessage:String, socket:SocketIOClient) { static func parseSocketMessage(stringMessage:String, socket:SocketIOClient) {
if stringMessage == "" { if stringMessage == "" {
return return
} }
func checkNSP(nsp:String) -> Bool { func checkNSP(nsp:String) -> Bool {
return nsp == "" && socket.nsp != "/" return nsp == "" && socket.nsp != "/"
} }
let p = parseString(stringMessage) as SocketPacket! let p = parseString(stringMessage) as SocketPacket!
if p.type == SocketPacketType.EVENT { if p.type == SocketPacketType.EVENT {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
socket.handleEvent(p.getEvent(), data: p.data, socket.handleEvent(p.getEvent(), data: p.data,
isInternalMessage: false, wantsAck: p.id) isInternalMessage: false, wantsAck: p.id)
} else if p.type == SocketPacketType.ACK { } else if p.type == SocketPacketType.ACK {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
socket.handleAck(p.id!, data: p.data) socket.handleAck(p.id!, data: p.data)
} else if p.type == SocketPacketType.BINARY_EVENT { } else if p.type == SocketPacketType.BINARY_EVENT {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
socket.waitingData.append(p) socket.waitingData.append(p)
} else if p.type == SocketPacketType.BINARY_ACK { } else if p.type == SocketPacketType.BINARY_ACK {
if checkNSP(p.nsp) { if checkNSP(p.nsp) {
return return
} }
p.justAck = true p.justAck = true
socket.waitingData.append(p) socket.waitingData.append(p)
} else if p.type == SocketPacketType.CONNECT { } else if p.type == SocketPacketType.CONNECT {
@ -224,27 +229,29 @@ class SocketParser {
} }
} else if p.type == SocketPacketType.DISCONNECT { } else if p.type == SocketPacketType.DISCONNECT {
socket.engineDidForceClose("Got Disconnect") socket.engineDidForceClose("Got Disconnect")
} else if p.type == SocketPacketType.ERROR {
socket.didError(p.data == nil ? "Error" : p.data!)
} }
} }
// Handles binary data // Handles binary data
static func parseBinaryData(data:NSData, socket:SocketIOClient) { static func parseBinaryData(data:NSData, socket:SocketIOClient) {
// NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros)) // NSLog(data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros))
if socket.waitingData.count == 0 { if socket.waitingData.count == 0 {
NSLog("Got data when not remaking packet") NSLog("Got data when not remaking packet")
return return
} }
let shouldExecute = socket.waitingData[0].addData(data) let shouldExecute = socket.waitingData[0].addData(data)
if !shouldExecute { if !shouldExecute {
return return
} }
let packet = socket.waitingData.removeAtIndex(0) let packet = socket.waitingData.removeAtIndex(0)
packet.fillInPlaceholders() packet.fillInPlaceholders()
if !packet.justAck { if !packet.justAck {
socket.handleEvent(packet.getEvent(), data: packet.data, socket.handleEvent(packet.getEvent(), data: packet.data,
wantsAck: packet.id) wantsAck: packet.id)