Use dispatch queues for buffering emitting and recieving
This commit is contained in:
parent
6d6ac0fc74
commit
b53d22f3a2
@ -29,6 +29,10 @@ typealias MultipleCallback = (NSArray?) -> Void
|
|||||||
|
|
||||||
class SocketIOClient: NSObject, SRWebSocketDelegate {
|
class SocketIOClient: NSObject, SRWebSocketDelegate {
|
||||||
let socketURL:NSMutableString!
|
let socketURL:NSMutableString!
|
||||||
|
let handleQueue = dispatch_queue_create("handleQueue".cStringUsingEncoding(NSUTF8StringEncoding),
|
||||||
|
DISPATCH_QUEUE_SERIAL)
|
||||||
|
let emitQueue = dispatch_queue_create("emitQueue".cStringUsingEncoding(NSUTF8StringEncoding),
|
||||||
|
DISPATCH_QUEUE_SERIAL)
|
||||||
private var secure = false
|
private var secure = false
|
||||||
private var handlers = [SocketEventHandler]()
|
private var handlers = [SocketEventHandler]()
|
||||||
private var lastSocketMessage:SocketEvent?
|
private var lastSocketMessage:SocketEvent?
|
||||||
@ -124,6 +128,10 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispatch_async(self.emitQueue) {self._emit(event, args)}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func _emit(event:String, _ args:[AnyObject]) {
|
||||||
var frame:SocketEvent
|
var frame:SocketEvent
|
||||||
var str:String
|
var str:String
|
||||||
var items = [AnyObject](count: args.count, repeatedValue: 1)
|
var items = [AnyObject](count: args.count, repeatedValue: 1)
|
||||||
@ -175,6 +183,10 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.connected {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if hasBinary {
|
if hasBinary {
|
||||||
str = SocketEvent.createMessageForEvent(event, withArgs: items,
|
str = SocketEvent.createMessageForEvent(event, withArgs: items,
|
||||||
hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp)
|
hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp)
|
||||||
@ -191,19 +203,27 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handles events
|
// Handles events
|
||||||
func handleEvent(#event:String, data:AnyObject?, multipleItems:Bool = false) {
|
func handleEvent(event:String, data:AnyObject?, multipleItems:Bool = false, internalMessage:Bool = false) {
|
||||||
// println("Should do event: \(event) with data: \(data)")
|
// println("Should do event: \(event) with data: \(data)")
|
||||||
|
if !self.connected && !internalMessage {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
for handler in self.handlers {
|
for handler in self.handlers {
|
||||||
if handler.event == event {
|
if handler.event == event {
|
||||||
if data is NSArray {
|
if data is NSArray {
|
||||||
|
dispatch_async(dispatch_get_main_queue()) {
|
||||||
handler.executeCallback(nil, items: (data as! NSArray))
|
handler.executeCallback(nil, items: (data as! NSArray))
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
dispatch_async(dispatch_get_main_queue()) {
|
||||||
handler.executeCallback(data)
|
handler.executeCallback(data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private func joinNamespace() {
|
private func joinNamespace() {
|
||||||
if self.nsp != nil {
|
if self.nsp != nil {
|
||||||
@ -354,7 +374,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
// Check for successful namepsace connect
|
// Check for successful namepsace connect
|
||||||
if self.nsp != nil {
|
if self.nsp != nil {
|
||||||
if stringMessage == "40/\(self.nsp!)" {
|
if stringMessage == "40/\(self.nsp!)" {
|
||||||
self.handleEvent(event: "connect", data: nil)
|
self.handleEvent("connect", data: nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,7 +433,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
// It would be nice if socket.io only allowed one thing
|
// It would be nice if socket.io only allowed one thing
|
||||||
// per message, but alas, it doesn't.
|
// per message, but alas, it doesn't.
|
||||||
if let parsed:AnyObject = SocketIOClient.parseData(data) {
|
if let parsed:AnyObject = SocketIOClient.parseData(data) {
|
||||||
self.handleEvent(event: event, data: parsed)
|
self.handleEvent(event, data: parsed)
|
||||||
return
|
return
|
||||||
} else if let strData = data {
|
} else if let strData = data {
|
||||||
// There are multiple items in the message
|
// There are multiple items in the message
|
||||||
@ -421,7 +441,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
// parseData to try and get an array.
|
// parseData to try and get an array.
|
||||||
let asArray = "[\(strData)]"
|
let asArray = "[\(strData)]"
|
||||||
if let parsed:AnyObject = SocketIOClient.parseData(asArray) {
|
if let parsed:AnyObject = SocketIOClient.parseData(asArray) {
|
||||||
self.handleEvent(event: event, data: parsed, multipleItems: true)
|
self.handleEvent(event, data: parsed, multipleItems: true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -431,7 +451,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
let noItemMessage = RegexMutable(messagePart)["\\[\"(.*?)\"]$"].groups()
|
let noItemMessage = RegexMutable(messagePart)["\\[\"(.*?)\"]$"].groups()
|
||||||
if noItemMessage != nil && noItemMessage.count == 2 {
|
if noItemMessage != nil && noItemMessage.count == 2 {
|
||||||
let event = noItemMessage[1]
|
let event = noItemMessage[1]
|
||||||
self.handleEvent(event: event, data: nil, multipleItems: false)
|
self.handleEvent(event, data: nil, multipleItems: false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -467,7 +487,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
|
|
||||||
if binaryGroup != nil {
|
if binaryGroup != nil {
|
||||||
// println(binaryGroup)
|
// println(binaryGroup)
|
||||||
var event:NSString!
|
var event:String!
|
||||||
var mutMessageObject:NSMutableString!
|
var mutMessageObject:NSMutableString!
|
||||||
var namespace:String?
|
var namespace:String?
|
||||||
let messageType = RegexMutable(binaryGroup[1])
|
let messageType = RegexMutable(binaryGroup[1])
|
||||||
@ -476,7 +496,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
// Check if message came from a namespace
|
// Check if message came from a namespace
|
||||||
if binaryGroup.count == 5 {
|
if binaryGroup.count == 5 {
|
||||||
namespace = binaryGroup[2]
|
namespace = binaryGroup[2]
|
||||||
event = RegexMutable(binaryGroup[3])["\""] ~= ""
|
event = (RegexMutable(binaryGroup[3])["\""] ~= "") as String
|
||||||
mutMessageObject = RegexMutable(binaryGroup[4])
|
mutMessageObject = RegexMutable(binaryGroup[4])
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -488,7 +508,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
let placeholdersRemoved = mutMessageObject["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"]
|
let placeholdersRemoved = mutMessageObject["(\\{\"_placeholder\":true,\"num\":(\\d*)\\})"]
|
||||||
~= "\"~~$2\""
|
~= "\"~~$2\""
|
||||||
|
|
||||||
let mes = SocketEvent(event: event as! String, args: placeholdersRemoved,
|
let mes = SocketEvent(event: event, args: placeholdersRemoved,
|
||||||
placeholders: numberOfPlaceholders.integerValue)
|
placeholders: numberOfPlaceholders.integerValue)
|
||||||
self.lastSocketMessage = mes
|
self.lastSocketMessage = mes
|
||||||
}
|
}
|
||||||
@ -508,10 +528,10 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
|
|
||||||
if let args:AnyObject = parsedArgs {
|
if let args:AnyObject = parsedArgs {
|
||||||
let filledInArgs:AnyObject = self.lastSocketMessage!.fillInPlaceholders(args)
|
let filledInArgs:AnyObject = self.lastSocketMessage!.fillInPlaceholders(args)
|
||||||
self.handleEvent(event: event, data: filledInArgs)
|
self.handleEvent(event, data: filledInArgs)
|
||||||
} else {
|
} else {
|
||||||
let filledInArgs:AnyObject = self.lastSocketMessage!.fillInPlaceholders()
|
let filledInArgs:AnyObject = self.lastSocketMessage!.fillInPlaceholders()
|
||||||
self.handleEvent(event: event, data: filledInArgs, multipleItems: true)
|
self.handleEvent(event, data: filledInArgs, multipleItems: true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,7 +555,8 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
self.connecting = false
|
self.connecting = false
|
||||||
self.reconnects = false
|
self.reconnects = false
|
||||||
self.reconnecting = false
|
self.reconnecting = false
|
||||||
self.handleEvent(event: "disconnect", data: "Failed to reconnect")
|
self.handleEvent("disconnect", data: "Failed to reconnect",
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
return
|
return
|
||||||
} else if self.connected {
|
} else if self.connected {
|
||||||
self.connecting = false
|
self.connecting = false
|
||||||
@ -544,7 +565,8 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// println("Trying to reconnect #\(reconnectAttempts - triesLeft)")
|
// println("Trying to reconnect #\(reconnectAttempts - triesLeft)")
|
||||||
self.handleEvent(event: "reconnectAttempt", data: triesLeft)
|
self.handleEvent("reconnectAttempt", data: triesLeft,
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
|
|
||||||
let waitTime = UInt64(self.reconnectWait) * NSEC_PER_SEC
|
let waitTime = UInt64(self.reconnectWait) * NSEC_PER_SEC
|
||||||
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(waitTime))
|
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(waitTime))
|
||||||
@ -567,7 +589,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
|
|
||||||
// Called when a message is recieved
|
// Called when a message is recieved
|
||||||
func webSocket(webSocket:SRWebSocket!, didReceiveMessage message:AnyObject?) {
|
func webSocket(webSocket:SRWebSocket!, didReceiveMessage message:AnyObject?) {
|
||||||
self.parseSocketMessage(message)
|
dispatch_async(self.handleQueue) {self.parseSocketMessage(message)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the socket is opened
|
// Called when the socket is opened
|
||||||
@ -583,7 +605,9 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.handleEvent(event: "connect", data: nil)
|
// Don't handle as internal because something crazy could happen where
|
||||||
|
// we disconnect before it's handled
|
||||||
|
self.handleEvent("connect", data: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the socket is closed
|
// Called when the socket is closed
|
||||||
@ -592,9 +616,11 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
self.connected = false
|
self.connected = false
|
||||||
self.connecting = false
|
self.connecting = false
|
||||||
if self.closed || !self.reconnects {
|
if self.closed || !self.reconnects {
|
||||||
self.handleEvent(event: "disconnect", data: reason)
|
self.handleEvent("disconnect", data: reason,
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
} else {
|
} else {
|
||||||
self.handleEvent(event: "reconnect", data: reason)
|
self.handleEvent("reconnect", data: reason,
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
self.tryReconnect(triesLeft: self.reconnectAttempts)
|
self.tryReconnect(triesLeft: self.reconnectAttempts)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -605,11 +631,14 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
|
|||||||
self.pingTimer?.invalidate()
|
self.pingTimer?.invalidate()
|
||||||
self.connected = false
|
self.connected = false
|
||||||
self.connecting = false
|
self.connecting = false
|
||||||
self.handleEvent(event: "error", data: error.localizedDescription)
|
self.handleEvent("error", data: error.localizedDescription,
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
if self.closed || !self.reconnects {
|
if self.closed || !self.reconnects {
|
||||||
self.handleEvent(event: "disconnect", data: error.localizedDescription)
|
self.handleEvent("disconnect", data: error.localizedDescription,
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
} else if !self.reconnecting {
|
} else if !self.reconnecting {
|
||||||
self.handleEvent(event: "reconnect", data: error.localizedDescription)
|
self.handleEvent("reconnect", data: error.localizedDescription,
|
||||||
|
multipleItems: false, internalMessage: true)
|
||||||
self.tryReconnect(triesLeft: self.reconnectAttempts)
|
self.tryReconnect(triesLeft: self.reconnectAttempts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user