use int for enum
This commit is contained in:
parent
eb5d03c88b
commit
14487a1beb
@ -59,7 +59,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
var connected:Bool {
|
var connected:Bool {
|
||||||
return self._connected
|
return self._connected
|
||||||
}
|
}
|
||||||
|
|
||||||
weak var client:SocketEngineClient?
|
weak var client:SocketEngineClient?
|
||||||
var cookies:[NSHTTPCookie]?
|
var cookies:[NSHTTPCookie]?
|
||||||
var pingInterval:Int?
|
var pingInterval:Int?
|
||||||
@ -74,16 +74,24 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
}
|
}
|
||||||
var ws:WebSocket?
|
var ws:WebSocket?
|
||||||
|
|
||||||
public enum PacketType:String {
|
public enum PacketType:Int {
|
||||||
case OPEN = "0"
|
case OPEN = 0
|
||||||
case CLOSE = "1"
|
case CLOSE = 1
|
||||||
case PING = "2"
|
case PING = 2
|
||||||
case PONG = "3"
|
case PONG = 3
|
||||||
case MESSAGE = "4"
|
case MESSAGE = 4
|
||||||
case UPGRADE = "5"
|
case UPGRADE = 5
|
||||||
case NOOP = "6"
|
case NOOP = 6
|
||||||
|
|
||||||
|
init(str:String) {
|
||||||
|
if let value = str.toInt() {
|
||||||
|
self = PacketType(rawValue: value)!
|
||||||
|
} else {
|
||||||
|
self = PacketType.NOOP
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(client:SocketEngineClient, forcePolling:Bool,
|
public init(client:SocketEngineClient, forcePolling:Bool,
|
||||||
forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?) {
|
forceWebsockets:Bool, withCookies cookies:[NSHTTPCookie]?) {
|
||||||
self.client = client
|
self.client = client
|
||||||
@ -93,19 +101,19 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(),
|
self.session = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(),
|
||||||
delegate: nil, delegateQueue: self.workQueue)
|
delegate: nil, delegateQueue: self.workQueue)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func close(#fast:Bool) {
|
public func close(#fast:Bool) {
|
||||||
self.pingTimer?.invalidate()
|
self.pingTimer?.invalidate()
|
||||||
self.closed = true
|
self.closed = true
|
||||||
|
|
||||||
self.write("", withType: PacketType.CLOSE, withData: nil)
|
self.write("", withType: PacketType.CLOSE, withData: nil)
|
||||||
self.ws?.disconnect()
|
self.ws?.disconnect()
|
||||||
|
|
||||||
if fast || self.polling {
|
if fast || self.polling {
|
||||||
self.client?.didForceClose("Disconnect")
|
self.client?.didForceClose("Disconnect")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) {
|
private func createBinaryDataForSend(data:NSData) -> (NSData?, String?) {
|
||||||
if self.websocket {
|
if self.websocket {
|
||||||
var byteArray = [UInt8](count: 1, repeatedValue: 0x0)
|
var byteArray = [UInt8](count: 1, repeatedValue: 0x0)
|
||||||
@ -117,20 +125,20 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
var str = "b4"
|
var str = "b4"
|
||||||
str += data.base64EncodedStringWithOptions(
|
str += data.base64EncodedStringWithOptions(
|
||||||
NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
|
NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
|
||||||
|
|
||||||
return (nil, str)
|
return (nil, str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createURLs(params:[String: AnyObject]?) -> (String, String) {
|
private func createURLs(params:[String: AnyObject]?) -> (String, String) {
|
||||||
if self.client == nil {
|
if self.client == nil {
|
||||||
return ("", "")
|
return ("", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = "\(self.client!.socketURL)/socket.io/?transport="
|
var url = "\(self.client!.socketURL)/socket.io/?transport="
|
||||||
var urlPolling:String
|
var urlPolling:String
|
||||||
var urlWebSocket:String
|
var urlWebSocket:String
|
||||||
|
|
||||||
if self.client!.secure {
|
if self.client!.secure {
|
||||||
urlPolling = "https://" + url + "polling"
|
urlPolling = "https://" + url + "polling"
|
||||||
urlWebSocket = "wss://" + url + "websocket"
|
urlWebSocket = "wss://" + url + "websocket"
|
||||||
@ -138,14 +146,14 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
urlPolling = "http://" + url + "polling"
|
urlPolling = "http://" + url + "polling"
|
||||||
urlWebSocket = "ws://" + url + "websocket"
|
urlWebSocket = "ws://" + url + "websocket"
|
||||||
}
|
}
|
||||||
|
|
||||||
if params != nil {
|
if params != nil {
|
||||||
for (key, value) in params! {
|
for (key, value) in params! {
|
||||||
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
|
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
|
||||||
NSCharacterSet.URLHostAllowedCharacterSet())!
|
NSCharacterSet.URLHostAllowedCharacterSet())!
|
||||||
urlPolling += "&\(keyEsc)="
|
urlPolling += "&\(keyEsc)="
|
||||||
urlWebSocket += "&\(keyEsc)="
|
urlWebSocket += "&\(keyEsc)="
|
||||||
|
|
||||||
if value is String {
|
if value is String {
|
||||||
let valueEsc = (value as! String).stringByAddingPercentEncodingWithAllowedCharacters(
|
let valueEsc = (value as! String).stringByAddingPercentEncodingWithAllowedCharacters(
|
||||||
NSCharacterSet.URLHostAllowedCharacterSet())!
|
NSCharacterSet.URLHostAllowedCharacterSet())!
|
||||||
@ -157,26 +165,26 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (urlPolling, urlWebSocket)
|
return (urlPolling, urlWebSocket)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func createWebsocket(andConnect connect:Bool) {
|
private func createWebsocket(andConnect connect:Bool) {
|
||||||
self.ws = WebSocket(url: NSURL(string: self.urlWebSocket! + "&sid=\(self.sid)")!)
|
self.ws = WebSocket(url: NSURL(string: self.urlWebSocket! + "&sid=\(self.sid)")!)
|
||||||
self.ws?.queue = self.handleQueue
|
self.ws?.queue = self.handleQueue
|
||||||
self.ws?.delegate = self
|
self.ws?.delegate = self
|
||||||
|
|
||||||
if connect {
|
if connect {
|
||||||
self.ws?.connect()
|
self.ws?.connect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func doFastUpgrade() {
|
private func doFastUpgrade() {
|
||||||
if self.waitingForPoll {
|
if self.waitingForPoll {
|
||||||
NSLog("Outstanding poll when switched to websockets," +
|
NSLog("Outstanding poll when switched to websockets," +
|
||||||
"we'll probably disconnect soon. You should report this.")
|
"we'll probably disconnect soon. You should report this.")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil)
|
self.sendWebSocketMessage("", withType: PacketType.UPGRADE, datas: nil)
|
||||||
self._websocket = true
|
self._websocket = true
|
||||||
self._polling = false
|
self._polling = false
|
||||||
@ -184,25 +192,25 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.probing = false
|
self.probing = false
|
||||||
self.flushProbeWait()
|
self.flushProbeWait()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func doPoll() {
|
private func doPoll() {
|
||||||
if self.websocket || self.waitingForPoll || !self.connected {
|
if self.websocket || self.waitingForPoll || !self.connected {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.waitingForPoll = true
|
self.waitingForPoll = true
|
||||||
let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)&b64=1")!)
|
let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)&b64=1")!)
|
||||||
|
|
||||||
self.doRequest(req)
|
self.doRequest(req)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func doRequest(req:NSMutableURLRequest) {
|
private func doRequest(req:NSMutableURLRequest) {
|
||||||
if !self.polling {
|
if !self.polling {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
|
req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
|
||||||
|
|
||||||
// NSLog("Doing request: \(req)")
|
// NSLog("Doing request: \(req)")
|
||||||
self.session.dataTaskWithRequest(req) {[weak self] data, res, err in
|
self.session.dataTaskWithRequest(req) {[weak self] data, res, err in
|
||||||
if self == nil {
|
if self == nil {
|
||||||
@ -213,21 +221,21 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
} else {
|
} else {
|
||||||
NSLog(err.localizedDescription)
|
NSLog(err.localizedDescription)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// NSLog("Got response: \(res)")
|
// NSLog("Got response: \(res)")
|
||||||
|
|
||||||
if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
|
if let str = NSString(data: data, encoding: NSUTF8StringEncoding) as? String {
|
||||||
dispatch_async(self!.parseQueue) {
|
dispatch_async(self!.parseQueue) {
|
||||||
self?.parsePollingMessage(str)
|
self?.parsePollingMessage(str)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self?.waitingForPoll = false
|
self?.waitingForPoll = false
|
||||||
|
|
||||||
if self!.fastUpgrade {
|
if self!.fastUpgrade {
|
||||||
self?.doFastUpgrade()
|
self?.doFastUpgrade()
|
||||||
return
|
return
|
||||||
@ -236,26 +244,26 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
}
|
}
|
||||||
}.resume()
|
}.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func flushProbeWait() {
|
private func flushProbeWait() {
|
||||||
// NSLog("flushing probe wait")
|
// NSLog("flushing probe wait")
|
||||||
dispatch_async(self.emitQueue) {[weak self] in
|
dispatch_async(self.emitQueue) {[weak self] in
|
||||||
if self == nil {
|
if self == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for waiter in self!.probeWait {
|
for waiter in self!.probeWait {
|
||||||
self?.write(waiter.msg, withType: waiter.type, withData: waiter.data)
|
self?.write(waiter.msg, withType: waiter.type, withData: waiter.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
self?.probeWait.removeAll(keepCapacity: false)
|
self?.probeWait.removeAll(keepCapacity: false)
|
||||||
|
|
||||||
if self?.postWait.count != 0 {
|
if self?.postWait.count != 0 {
|
||||||
self?.flushWaitingForPostToWebSocket()
|
self?.flushWaitingForPostToWebSocket()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func flushWaitingForPost() {
|
private func flushWaitingForPost() {
|
||||||
if self.postWait.count == 0 || !self.connected {
|
if self.postWait.count == 0 || !self.connected {
|
||||||
return
|
return
|
||||||
@ -263,33 +271,33 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.flushWaitingForPostToWebSocket()
|
self.flushWaitingForPostToWebSocket()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var postStr = ""
|
var postStr = ""
|
||||||
|
|
||||||
for packet in self.postWait {
|
for packet in self.postWait {
|
||||||
let len = count(packet)
|
let len = count(packet)
|
||||||
|
|
||||||
postStr += "\(len):\(packet)"
|
postStr += "\(len):\(packet)"
|
||||||
}
|
}
|
||||||
|
|
||||||
self.postWait.removeAll(keepCapacity: false)
|
self.postWait.removeAll(keepCapacity: false)
|
||||||
|
|
||||||
let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)")!)
|
let req = NSMutableURLRequest(URL: NSURL(string: self.urlPolling! + "&sid=\(self.sid)")!)
|
||||||
|
|
||||||
req.HTTPMethod = "POST"
|
req.HTTPMethod = "POST"
|
||||||
req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
|
req.setValue("text/plain; charset=UTF-8", forHTTPHeaderField: "Content-Type")
|
||||||
|
|
||||||
let postData = postStr.dataUsingEncoding(NSUTF8StringEncoding,
|
let postData = postStr.dataUsingEncoding(NSUTF8StringEncoding,
|
||||||
allowLossyConversion: false)!
|
allowLossyConversion: false)!
|
||||||
|
|
||||||
req.HTTPBody = postData
|
req.HTTPBody = postData
|
||||||
req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")
|
req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")
|
||||||
|
|
||||||
self.waitingForPost = true
|
self.waitingForPost = true
|
||||||
|
|
||||||
// NSLog("posting: \(postStr)")
|
// NSLog("posting: \(postStr)")
|
||||||
// NSLog("Posting with WS status of: \(self.websocket)")
|
// NSLog("Posting with WS status of: \(self.websocket)")
|
||||||
|
|
||||||
self.session.dataTaskWithRequest(req) {[weak self] data, res, err in
|
self.session.dataTaskWithRequest(req) {[weak self] data, res, err in
|
||||||
if self == nil {
|
if self == nil {
|
||||||
return
|
return
|
||||||
@ -300,7 +308,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
NSLog(err.localizedDescription)
|
NSLog(err.localizedDescription)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self?.waitingForPost = false
|
self?.waitingForPost = false
|
||||||
dispatch_async(self!.emitQueue) {
|
dispatch_async(self!.emitQueue) {
|
||||||
if !self!.fastUpgrade {
|
if !self!.fastUpgrade {
|
||||||
@ -309,90 +317,90 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
}
|
}
|
||||||
}}.resume()
|
}}.resume()
|
||||||
}
|
}
|
||||||
|
|
||||||
// We had packets waiting for send when we upgraded
|
// We had packets waiting for send when we upgraded
|
||||||
// Send them raw
|
// Send them raw
|
||||||
private func flushWaitingForPostToWebSocket() {
|
private func flushWaitingForPostToWebSocket() {
|
||||||
for msg in self.postWait {
|
for msg in self.postWait {
|
||||||
self.ws?.writeString(msg)
|
self.ws?.writeString(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.postWait.removeAll(keepCapacity: true)
|
self.postWait.removeAll(keepCapacity: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A poll failed, tell the client about it
|
// A poll failed, tell the client about it
|
||||||
|
|
||||||
private func handlePollingFailed(reason:String) {
|
private func handlePollingFailed(reason:String) {
|
||||||
self._connected = false
|
self._connected = false
|
||||||
self.ws?.disconnect()
|
self.ws?.disconnect()
|
||||||
self.pingTimer?.invalidate()
|
self.pingTimer?.invalidate()
|
||||||
self.waitingForPoll = false
|
self.waitingForPoll = false
|
||||||
self.waitingForPost = false
|
self.waitingForPost = false
|
||||||
|
|
||||||
if self.client == nil {
|
if self.client == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.closed && !self.client!.reconnecting {
|
if !self.closed && !self.client!.reconnecting {
|
||||||
self.client?.pollingDidFail(reason)
|
self.client?.pollingDidFail(reason)
|
||||||
} else if !self.client!.reconnecting {
|
} else if !self.client!.reconnecting {
|
||||||
self.client?.didForceClose(reason)
|
self.client?.didForceClose(reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func open(opts:[String: AnyObject]? = nil) {
|
public func open(opts:[String: AnyObject]? = nil) {
|
||||||
if self.connected {
|
if self.connected {
|
||||||
fatalError("Engine tried to open while connected")
|
fatalError("Engine tried to open while connected")
|
||||||
}
|
}
|
||||||
|
|
||||||
self.closed = false
|
self.closed = false
|
||||||
let (urlPolling, urlWebSocket) = self.createURLs(opts)
|
let (urlPolling, urlWebSocket) = self.createURLs(opts)
|
||||||
self.urlPolling = urlPolling
|
self.urlPolling = urlPolling
|
||||||
self.urlWebSocket = urlWebSocket
|
self.urlWebSocket = urlWebSocket
|
||||||
|
|
||||||
if self.forceWebsockets {
|
if self.forceWebsockets {
|
||||||
self._polling = false
|
self._polling = false
|
||||||
self._websocket = true
|
self._websocket = true
|
||||||
self.createWebsocket(andConnect: true)
|
self.createWebsocket(andConnect: true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&b64=1")!)
|
let reqPolling = NSMutableURLRequest(URL: NSURL(string: urlPolling + "&b64=1")!)
|
||||||
|
|
||||||
if self.cookies != nil {
|
if self.cookies != nil {
|
||||||
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(self.cookies!)
|
let headers = NSHTTPCookie.requestHeaderFieldsWithCookies(self.cookies!)
|
||||||
reqPolling.allHTTPHeaderFields = headers
|
reqPolling.allHTTPHeaderFields = headers
|
||||||
}
|
}
|
||||||
|
|
||||||
self.doRequest(reqPolling)
|
self.doRequest(reqPolling)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translatation of engine.io-parser#decodePayload
|
// Translatation of engine.io-parser#decodePayload
|
||||||
private func parsePollingMessage(str:String) {
|
private func parsePollingMessage(str:String) {
|
||||||
if str.length == 1 {
|
if str.length == 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// println(str)
|
// println(str)
|
||||||
|
|
||||||
let strArray = Array(str)
|
let strArray = Array(str)
|
||||||
var length = ""
|
var length = ""
|
||||||
var n = 0
|
var n = 0
|
||||||
var msg = ""
|
var msg = ""
|
||||||
|
|
||||||
func testLength(length:String, inout n:Int) -> Bool {
|
func testLength(length:String, inout n:Int) -> Bool {
|
||||||
if let num = length.toInt() {
|
if let num = length.toInt() {
|
||||||
n = num
|
n = num
|
||||||
} else {
|
} else {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
for var i = 0, l = str.length; i < l; i = i &+ 1 {
|
for var i = 0, l = str.length; i < l; i = i &+ 1 {
|
||||||
let chr = String(strArray[i])
|
let chr = String(strArray[i])
|
||||||
|
|
||||||
if chr != ":" {
|
if chr != ":" {
|
||||||
length += chr
|
length += chr
|
||||||
} else {
|
} else {
|
||||||
@ -401,16 +409,16 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.handlePollingFailed("Error parsing XHR message")
|
self.handlePollingFailed("Error parsing XHR message")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = String(strArray[i&+1...i&+n])
|
msg = String(strArray[i&+1...i&+n])
|
||||||
|
|
||||||
if let lengthInt = length.toInt() {
|
if let lengthInt = length.toInt() {
|
||||||
if lengthInt != msg.length {
|
if lengthInt != msg.length {
|
||||||
NSLog("parsing error: \(str)")
|
NSLog("parsing error: \(str)")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if msg.length != 0 {
|
if msg.length != 0 {
|
||||||
// Be sure to capture the value of the msg
|
// Be sure to capture the value of the msg
|
||||||
dispatch_async(self.handleQueue) {[weak self, msg] in
|
dispatch_async(self.handleQueue) {[weak self, msg] in
|
||||||
@ -418,134 +426,126 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
i += n
|
i += n
|
||||||
length = ""
|
length = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func parseEngineData(data:NSData) {
|
private func parseEngineData(data:NSData) {
|
||||||
if self.client == nil {
|
if self.client == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch_async(self.client!.handleQueue) {[weak self] in
|
dispatch_async(self.client!.handleQueue) {[weak self] in
|
||||||
self?.client?.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1)))
|
self?.client?.parseBinaryData(data.subdataWithRange(NSMakeRange(1, data.length - 1)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func parseEngineMessage(var message:String, fromPolling:Bool) {
|
private func parseEngineMessage(var message:String, fromPolling:Bool) {
|
||||||
// NSLog("Engine got message: \(message)")
|
// NSLog("Engine got message: \(message)")
|
||||||
if fromPolling {
|
if fromPolling {
|
||||||
fixDoubleUTF8(&message)
|
fixDoubleUTF8(&message)
|
||||||
}
|
}
|
||||||
|
|
||||||
let type = message["^(\\d)"].groups()?[1]
|
let type = PacketType(str: (message["^(\\d)"].groups()?[1])!)
|
||||||
|
|
||||||
if type != PacketType.MESSAGE.rawValue {
|
if type == PacketType.MESSAGE {
|
||||||
// TODO Handle other packets
|
// Remove message type
|
||||||
|
message.removeAtIndex(message.startIndex)
|
||||||
|
|
||||||
|
if self.client == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_async(self.client!.handleQueue) {[weak self] in
|
||||||
|
self?.client?.parseSocketMessage(message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if type == PacketType.NOOP {
|
||||||
|
self.doPoll()
|
||||||
|
return
|
||||||
|
} else if type == PacketType.PONG {
|
||||||
|
// We should upgrade
|
||||||
|
if message == "3probe" {
|
||||||
|
self.upgradeTransport()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
} else if type == PacketType.OPEN {
|
||||||
|
var err:NSError?
|
||||||
|
|
||||||
|
message.removeAtIndex(message.startIndex)
|
||||||
|
let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
|
||||||
|
|
||||||
|
if let json = NSJSONSerialization.JSONObjectWithData(mesData,
|
||||||
|
options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary {
|
||||||
|
if let sid = json["sid"] as? String {
|
||||||
|
// println(json)
|
||||||
|
self.sid = sid
|
||||||
|
self._connected = true
|
||||||
|
if !self.forcePolling && !self.forceWebsockets {
|
||||||
|
self.createWebsocket(andConnect: true)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NSLog("Error handshaking")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let pingInterval = json["pingInterval"] as? Int {
|
||||||
|
self.pingInterval = pingInterval / 1000
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fatalError("Error parsing engine connect")
|
||||||
|
}
|
||||||
|
|
||||||
|
self.startPingTimer()
|
||||||
|
|
||||||
|
if !self.forceWebsockets {
|
||||||
|
self.doPoll()
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
} else if type == PacketType.CLOSE {
|
||||||
|
if self.client == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.polling {
|
||||||
|
self.client!.didForceClose("Disconnect")
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
} else {
|
||||||
if message.hasPrefix("b4") {
|
if message.hasPrefix("b4") {
|
||||||
// binary in base64 string
|
// binary in base64 string
|
||||||
|
|
||||||
message.removeRange(Range<String.Index>(start: message.startIndex,
|
message.removeRange(Range<String.Index>(start: message.startIndex,
|
||||||
end: advance(message.startIndex, 2)))
|
end: advance(message.startIndex, 2)))
|
||||||
|
|
||||||
if let data = NSData(base64EncodedString: message,
|
if let data = NSData(base64EncodedString: message,
|
||||||
options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters) {
|
options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
|
||||||
|
where self.client != nil {
|
||||||
// println("sending \(data)")
|
// println("sending \(data)")
|
||||||
|
|
||||||
if self.client == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_async(self.client!.handleQueue) {[weak self] in
|
dispatch_async(self.client!.handleQueue) {[weak self] in
|
||||||
self?.client?.parseBinaryData(data)
|
self?.client?.parseBinaryData(data)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
} else if type == PacketType.NOOP.rawValue {
|
|
||||||
self.doPoll()
|
|
||||||
return
|
|
||||||
} else if type == PacketType.PONG.rawValue {
|
|
||||||
// We should upgrade
|
|
||||||
if message == "3probe" {
|
|
||||||
self.upgradeTransport()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
} else if type == PacketType.OPEN.rawValue {
|
|
||||||
var err:NSError?
|
|
||||||
|
|
||||||
message.removeAtIndex(message.startIndex)
|
|
||||||
let mesData = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
|
|
||||||
|
|
||||||
if let json = NSJSONSerialization.JSONObjectWithData(mesData,
|
|
||||||
options: NSJSONReadingOptions.AllowFragments, error: &err) as? NSDictionary {
|
|
||||||
if let sid = json["sid"] as? String {
|
|
||||||
// println(json)
|
|
||||||
self.sid = sid
|
|
||||||
self._connected = true
|
|
||||||
if !self.forcePolling && !self.forceWebsockets {
|
|
||||||
self.createWebsocket(andConnect: true)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NSLog("Error handshaking")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let pingInterval = json["pingInterval"] as? Int {
|
|
||||||
self.pingInterval = pingInterval / 1000
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fatalError("Error parsing engine connect")
|
|
||||||
}
|
|
||||||
|
|
||||||
self.startPingTimer()
|
|
||||||
|
|
||||||
if !self.forceWebsockets {
|
|
||||||
self.doPoll()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
} else if type == PacketType.CLOSE.rawValue {
|
|
||||||
if self.client == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.polling {
|
|
||||||
self.client!.didForceClose("Disconnect")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// println("Got something idk what to do with")
|
|
||||||
// println(messageString)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove message type
|
|
||||||
message.removeAtIndex(message.startIndex)
|
|
||||||
|
|
||||||
if self.client == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_async(self.client!.handleQueue) {[weak self] in
|
|
||||||
self?.client?.parseSocketMessage(message)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func probeWebSocket() {
|
private func probeWebSocket() {
|
||||||
if self.websocketConnected {
|
if self.websocketConnected {
|
||||||
self.sendWebSocketMessage("probe", withType: PacketType.PING)
|
self.sendWebSocketMessage("probe", withType: PacketType.PING)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send an engine message (4)
|
/// Send an engine message (4)
|
||||||
public func send(msg:String, withData datas:ContiguousArray<NSData>?) {
|
public func send(msg:String, withData datas:ContiguousArray<NSData>?) {
|
||||||
if self.probing {
|
if self.probing {
|
||||||
@ -554,11 +554,11 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.write(msg, withType: PacketType.MESSAGE, withData: datas)
|
self.write(msg, withType: PacketType.MESSAGE, withData: datas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendPing() {
|
func sendPing() {
|
||||||
self.write("", withType: PacketType.PING, withData: nil)
|
self.write("", withType: PacketType.PING, withData: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send polling message.
|
/// Send polling message.
|
||||||
/// Only call on emitQueue
|
/// Only call on emitQueue
|
||||||
private func sendPollMessage(var msg:String, withType type:PacketType,
|
private func sendPollMessage(var msg:String, withType type:PacketType,
|
||||||
@ -566,29 +566,29 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
// println("Sending poll: \(msg) as type: \(type.rawValue)")
|
// println("Sending poll: \(msg) as type: \(type.rawValue)")
|
||||||
doubleEncodeUTF8(&msg)
|
doubleEncodeUTF8(&msg)
|
||||||
let strMsg = "\(type.rawValue)\(msg)"
|
let strMsg = "\(type.rawValue)\(msg)"
|
||||||
|
|
||||||
self.postWait.append(strMsg)
|
self.postWait.append(strMsg)
|
||||||
|
|
||||||
if datas != nil {
|
if datas != nil {
|
||||||
for data in datas! {
|
for data in datas! {
|
||||||
let (nilData, b64Data) = self.createBinaryDataForSend(data)
|
let (nilData, b64Data) = self.createBinaryDataForSend(data)
|
||||||
|
|
||||||
self.postWait.append(b64Data!)
|
self.postWait.append(b64Data!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.waitingForPost {
|
if !self.waitingForPost {
|
||||||
self.flushWaitingForPost()
|
self.flushWaitingForPost()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send message on WebSockets
|
/// Send message on WebSockets
|
||||||
/// Only call on emitQueue
|
/// Only call on emitQueue
|
||||||
private func sendWebSocketMessage(str:String, withType type:PacketType,
|
private func sendWebSocketMessage(str:String, withType type:PacketType,
|
||||||
datas:ContiguousArray<NSData>? = nil) {
|
datas:ContiguousArray<NSData>? = nil) {
|
||||||
// println("Sending ws: \(str) as type: \(type.rawValue)")
|
// println("Sending ws: \(str) as type: \(type.rawValue)")
|
||||||
self.ws?.writeString("\(type.rawValue)\(str)")
|
self.ws?.writeString("\(type.rawValue)\(str)")
|
||||||
|
|
||||||
if datas != nil {
|
if datas != nil {
|
||||||
for data in datas! {
|
for data in datas! {
|
||||||
let (data, nilString) = self.createBinaryDataForSend(data)
|
let (data, nilString) = self.createBinaryDataForSend(data)
|
||||||
@ -598,13 +598,13 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starts the ping timer
|
// Starts the ping timer
|
||||||
private func startPingTimer() {
|
private func startPingTimer() {
|
||||||
if self.pingInterval == nil {
|
if self.pingInterval == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pingTimer?.invalidate()
|
self.pingTimer?.invalidate()
|
||||||
dispatch_async(dispatch_get_main_queue()) {
|
dispatch_async(dispatch_get_main_queue()) {
|
||||||
self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(self.pingInterval!),
|
self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(self.pingInterval!),
|
||||||
@ -612,7 +612,7 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
selector: Selector("sendPing"), userInfo: nil, repeats: true)
|
selector: Selector("sendPing"), userInfo: nil, repeats: true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func upgradeTransport() {
|
private func upgradeTransport() {
|
||||||
if self.websocketConnected {
|
if self.websocketConnected {
|
||||||
// NSLog("Doing fast upgrade")
|
// NSLog("Doing fast upgrade")
|
||||||
@ -622,13 +622,13 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.sendPollMessage("", withType: PacketType.NOOP)
|
self.sendPollMessage("", withType: PacketType.NOOP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func write(msg:String, withType type:PacketType, withData data:ContiguousArray<NSData>?) {
|
public func write(msg:String, withType type:PacketType, withData data:ContiguousArray<NSData>?) {
|
||||||
dispatch_async(self.emitQueue) {[weak self] in
|
dispatch_async(self.emitQueue) {[weak self] in
|
||||||
if self == nil || !self!.connected {
|
if self == nil || !self!.connected {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if self!.websocket {
|
if self!.websocket {
|
||||||
// NSLog("writing ws: \(msg):\(data)")
|
// NSLog("writing ws: \(msg):\(data)")
|
||||||
self?.sendWebSocketMessage(msg, withType: type, datas: data)
|
self?.sendWebSocketMessage(msg, withType: type, datas: data)
|
||||||
@ -638,12 +638,12 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delagate methods
|
// Delagate methods
|
||||||
|
|
||||||
public func websocketDidConnect(socket:WebSocket) {
|
public func websocketDidConnect(socket:WebSocket) {
|
||||||
self.websocketConnected = true
|
self.websocketConnected = true
|
||||||
|
|
||||||
if !self.forceWebsockets {
|
if !self.forceWebsockets {
|
||||||
self.probing = true
|
self.probing = true
|
||||||
self.probeWebSocket()
|
self.probeWebSocket()
|
||||||
@ -653,21 +653,21 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self._polling = false
|
self._polling = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func websocketDidDisconnect(socket:WebSocket, error:NSError?) {
|
public func websocketDidDisconnect(socket:WebSocket, error:NSError?) {
|
||||||
self.websocketConnected = false
|
self.websocketConnected = false
|
||||||
self.probing = false
|
self.probing = false
|
||||||
|
|
||||||
if self.closed {
|
if self.closed {
|
||||||
self.client?.didForceClose("Disconnect")
|
self.client?.didForceClose("Disconnect")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.websocket {
|
if self.websocket {
|
||||||
self.pingTimer?.invalidate()
|
self.pingTimer?.invalidate()
|
||||||
self._connected = false
|
self._connected = false
|
||||||
self._websocket = false
|
self._websocket = false
|
||||||
|
|
||||||
let reason = error?.localizedDescription
|
let reason = error?.localizedDescription
|
||||||
self.client?.webSocketDidCloseWithCode(1,
|
self.client?.webSocketDidCloseWithCode(1,
|
||||||
reason: reason == nil ? "Socket Disconnected" : reason!)
|
reason: reason == nil ? "Socket Disconnected" : reason!)
|
||||||
@ -675,11 +675,11 @@ public class SocketEngine: NSObject, WebSocketDelegate {
|
|||||||
self.flushProbeWait()
|
self.flushProbeWait()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func websocketDidReceiveMessage(socket:WebSocket, text:String) {
|
public func websocketDidReceiveMessage(socket:WebSocket, text:String) {
|
||||||
self.parseEngineMessage(text, fromPolling: false)
|
self.parseEngineMessage(text, fromPolling: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func websocketDidReceiveData(socket:WebSocket, data:NSData) {
|
public func websocketDidReceiveData(socket:WebSocket, data:NSData) {
|
||||||
self.parseEngineData(data)
|
self.parseEngineData(data)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user