better parsing

This commit is contained in:
Erik 2015-03-20 10:51:26 -04:00
parent cbc59d6004
commit 4832be5c8a
5 changed files with 65 additions and 93 deletions

View File

@ -81,7 +81,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
} }
var ws:WebSocket? var ws:WebSocket?
init(client:SocketEngineClient, forcePolling:Bool = false, withCookies cookies:[NSHTTPCookie]?) { init(client:SocketEngineClient, forcePolling:Bool, withCookies cookies:[NSHTTPCookie]?) {
self.client = client self.client = client
self.forcePolling = forcePolling self.forcePolling = forcePolling
self.cookies = cookies self.cookies = cookies

View File

@ -28,14 +28,12 @@ public typealias NormalCallback = (NSArray?, AckEmitter?) -> Void
public typealias AnyHandler = (event:String, items:AnyObject?) public typealias AnyHandler = (event:String, items:AnyObject?)
public typealias AckEmitter = (AnyObject...) -> Void public typealias AckEmitter = (AnyObject...) -> Void
private func emitAckCallback(socket:SocketIOClient, num:Int, type:Int) -> AckEmitter { private func emitAckCallback(socket:SocketIOClient, num:Int, type:Int)
func emitter(items:AnyObject...) { // Curried
(items:AnyObject...) -> Void {
socket.emitAck(num, withData: items, withAckType: type) socket.emitAck(num, withData: items, withAckType: type)
} }
return emitter
}
class SocketEventHandler { class SocketEventHandler {
let event:String! let event:String!
let callback:NormalCallback? let callback:NormalCallback?

View File

@ -75,6 +75,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
return self._sid return self._sid
} }
/**
Create a new SocketIOClient. opts can be omitted
*/
public init(var socketURL:String, opts:NSDictionary? = nil) { public init(var socketURL:String, opts:NSDictionary? = nil) {
if socketURL["https://"].matches().count != 0 { if socketURL["https://"].matches().count != 0 {
self._secure = true self._secure = true
@ -127,7 +130,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
self.init(socketURL: socketURL, opts: options) self.init(socketURL: socketURL, opts: options)
} }
// Closes the socket /**
Closes the socket. Only reopen the same socket if you know what you're doing.
*/
public func close() { public func close() {
self._closed = true self._closed = true
self._connecting = false self._connecting = false
@ -136,7 +141,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
self.engine?.close() self.engine?.close()
} }
// Connects to the server /**
Connect to the server.
*/
public func connect() { public func connect() {
if self.closed { if self.closed {
println("Warning! This socket was previously closed. This might be dangerous!") println("Warning! This socket was previously closed. This might be dangerous!")
@ -146,7 +153,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
self.engine?.open() self.engine?.open()
} }
// Connect to the server using params /**
Connect to the server with params that will be passed on connection.
*/
public func connectWithParams(params:[String: AnyObject]) { public func connectWithParams(params:[String: AnyObject]) {
if self.closed { if self.closed {
println("Warning! This socket was previously closed. This might be dangerous!") println("Warning! This socket was previously closed. This might be dangerous!")
@ -174,7 +183,7 @@ public class SocketIOClient: NSObject, SocketEngineClient {
self.handleEvent("connect", data: nil, isInternalMessage: false) self.handleEvent("connect", data: nil, isInternalMessage: false)
} }
// Server wants us to die /// Server wants us to die
func didForceClose(#message:String) { func didForceClose(#message:String) {
self._closed = true self._closed = true
self._connected = false self._connected = false
@ -184,9 +193,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
self.handleEvent("disconnect", data: message, isInternalMessage: true) self.handleEvent("disconnect", data: message, isInternalMessage: true)
} }
// Sends a message with multiple args /**
// If a message contains binary we have to send those Send a message to the server
// seperately. */
public func emit(event:String, _ args:AnyObject...) { public func emit(event:String, _ args:AnyObject...) {
if !self.connected { if !self.connected {
return return
@ -198,11 +207,17 @@ public class SocketIOClient: NSObject, SocketEngineClient {
} }
} }
// Objc doesn't have variadics /**
Same as emit, but meant for Objective-C
*/
public func emitObjc(event:String, withItems items:[AnyObject]) { public func emitObjc(event:String, withItems items:[AnyObject]) {
self.emit(event, items) self.emit(event, items)
} }
/**
Sends a message to the server, requesting an ack. Use the onAck method of SocketAckHandler to add
an ack.
*/
public func emitWithAck(event:String, _ args:AnyObject...) -> SocketAckHandler { public func emitWithAck(event:String, _ args:AnyObject...) -> SocketAckHandler {
if !self.connected { if !self.connected {
return SocketAckHandler(event: "fail", socket: self) return SocketAckHandler(event: "fail", socket: self)
@ -221,6 +236,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
return ackHandler return ackHandler
} }
/**
Same as emitWithAck, but for Objective-C
*/
public func emitWithAckObjc(event:String, withItems items:[AnyObject]) -> SocketAckHandler { public func emitWithAckObjc(event:String, withItems items:[AnyObject]) -> SocketAckHandler {
return self.emitWithAck(event, items) return self.emitWithAck(event, items)
} }
@ -265,6 +283,7 @@ public class SocketIOClient: NSObject, SocketEngineClient {
return return
} }
// println("sending ack: \(ack) \(data)")
let (items, hasBinary, emitDatas) = SocketParser.parseEmitArgs(data!) let (items, hasBinary, emitDatas) = SocketParser.parseEmitArgs(data!)
var str:String var str:String
@ -311,7 +330,9 @@ public class SocketIOClient: NSObject, SocketEngineClient {
} }
} }
// Handles events /**
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) { wantsAck ack:Int? = nil, withAckType ackType:Int = 3) {
// println("Should do event: \(event) with data: \(data)") // println("Should do event: \(event) with data: \(data)")
@ -363,18 +384,24 @@ public class SocketIOClient: NSObject, SocketEngineClient {
} }
} }
// Adds handler for an event /**
Adds a handler for an event.
*/
public func on(name:String, callback:NormalCallback) { public func on(name:String, callback:NormalCallback) {
let handler = SocketEventHandler(event: name, callback: callback) let handler = SocketEventHandler(event: name, callback: callback)
self.handlers.append(handler) self.handlers.append(handler)
} }
// Adds a handler for any event /**
Adds a handler that will be called on every event.
*/
public func onAny(handler:(AnyHandler) -> Void) { public func onAny(handler:(AnyHandler) -> Void) {
self.anyHandler = handler self.anyHandler = handler
} }
// Opens the connection to the socket /**
Same as connect
*/
public func open() { public func open() {
self.connect() self.connect()
} }

View File

@ -220,39 +220,20 @@ class SocketParser {
return return
} }
var messageGroups:[String]?
let type = stringMessage.removeAtIndex(stringMessage.startIndex) let type = stringMessage.removeAtIndex(stringMessage.startIndex)
if type == "2" { if type == "2" {
if let groups = stringMessage["(\\d*)\\/?(\\w*)?,?(\\d*)?\\[\"(.*?)\",?(.*?)?\\]$", if let groups = stringMessage["(\\/(\\w*))?,?(\\d*)?\\[\"(.*?)\",?(.*?)?\\]$",
NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { NSRegularExpressionOptions.DotMatchesLineSeparators].groups() {
messageGroups = groups let namespace = groups[2]
let ackNum = groups[3]
var mesNum = messageGroups![1] let event = groups[4]
var ackNum:String let data = "[\(groups[5])]"
var namespace:String?
if mesNum == "" {
ackNum = ""
} else if messageGroups![3] != "" {
ackNum = messageGroups![3]
} else {
let range = Range<String.Index>(start: mesNum.startIndex,
end: advance(mesNum.startIndex, 1))
mesNum.replaceRange(range, with: "")
ackNum = mesNum
}
namespace = messageGroups![2]
if namespace == "" && socket.nsp != nil { if namespace == "" && socket.nsp != nil {
return return
} }
let event = messageGroups![4]
let data = "[\(messageGroups![5])]"
if let parsed:AnyObject = self.parseData(data) { if let parsed:AnyObject = self.parseData(data) {
if ackNum == "" { if ackNum == "" {
socket.handleEvent(event, data: parsed) socket.handleEvent(event, data: parsed)
@ -264,25 +245,16 @@ class SocketParser {
} }
} }
} else if type == "3" { } else if type == "3" {
if let ackGroup = stringMessage["(\\d*)\\/?(\\w*)?,?(\\d*)?\\[(.*?)?\\]$", if let ackGroup = stringMessage["(\\/(\\w*))?,?(\\d*)?\\[(.*?)?\\]$",
NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { NSRegularExpressionOptions.DotMatchesLineSeparators].groups() {
messageGroups = ackGroup let nsp = ackGroup[2]
let ackNum = ackGroup[3]
let arr = Array(messageGroups![1]) let ackData:AnyObject? = self.parseData("[\(ackGroup[4])]")
var ackNum:String
let nsp = messageGroups![2]
if nsp == "" && socket.nsp != nil { if nsp == "" && socket.nsp != nil {
return return
} }
if nsp == "" {
ackNum = String(arr[0...arr.count-1])
} else {
ackNum = messageGroups![3]
}
let ackData:AnyObject? = self.parseData("[\(messageGroups![4])]")
socket.handleAck(ackNum.toInt()!, data: ackData) socket.handleAck(ackNum.toInt()!, data: ackData)
} }
} else { } else {
@ -346,32 +318,17 @@ class SocketParser {
// Tries to parse a message that contains binary // Tries to parse a message that contains binary
class func parseBinaryMessage(var message:String, socket:SocketIOClient) { class func parseBinaryMessage(var message:String, socket:SocketIOClient) {
// NSLog(message) // NSLog(message)
var binaryGroup:[String]?
let type = message.removeAtIndex(message.startIndex) let type = message.removeAtIndex(message.startIndex)
if type == "5" { if type == "5" {
if let groups = message["^(\\d*)-\\/?(\\w*)?,?(\\d*)?\\[(\".*?\")?,?(.*)?\\]$", if let groups = message["^(\\d*)-(\\/(\\w*))?,?(\\d*)?\\[\"(.*?)\",?(.*)?\\]$",
NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { NSRegularExpressionOptions.DotMatchesLineSeparators].groups() {
binaryGroup = groups let numberOfPlaceholders = groups[1]
let namespace = groups[3]
var ackNum:String let ackNum = groups[4]
var event:String let event = groups[5]
var mutMessageObject:String let mutMessageObject = groups[6]
var namespace:String?
let numberOfPlaceholders = binaryGroup![1]
namespace = binaryGroup![2]
if binaryGroup![3] != "" {
ackNum = binaryGroup![3] as String
} else if socket.nsp == nil && binaryGroup![2] != "" {
ackNum = binaryGroup![2]
} else {
ackNum = ""
}
event = (binaryGroup![4]["\""] ~= "") as String
mutMessageObject = binaryGroup![5]
if namespace == "" && socket.nsp != nil { if namespace == "" && socket.nsp != nil {
return return
@ -393,26 +350,16 @@ class SocketParser {
socket.waitingData.append(mes) socket.waitingData.append(mes)
} }
} else if type == "6" { } else if type == "6" {
if let groups = message["^(\\d*)-\\/?(\\w*)?,?(\\d*)?\\[(.*?)?\\]$", if let groups = message["^(\\d*)-(\\/(\\w*))?,?(\\d*)?\\[(.*?)?\\]$",
NSRegularExpressionOptions.DotMatchesLineSeparators].groups() { NSRegularExpressionOptions.DotMatchesLineSeparators].groups() {
binaryGroup = groups let numberOfPlaceholders = groups[1]
let namespace = groups[3]
let ackNum = groups[4]
let mutMessageObject = groups[5]
let numberOfPlaceholders = binaryGroup![1] if namespace == "" && socket.nsp != nil {
var ackNum:String
var nsp:String
if binaryGroup![3] == "" {
ackNum = binaryGroup![2]
nsp = ""
} else {
ackNum = binaryGroup![3]
nsp = binaryGroup![2]
}
if nsp == "" && socket.nsp != nil {
return return
} }
var mutMessageObject = binaryGroup![4]
let placeholdersRemoved = mutMessageObject["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"] let placeholdersRemoved = mutMessageObject["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"]
~= "\"~~$2\"" ~= "\"~~$2\""