Better handle moving between polling and websockets. Sending binary on polling still bork

This commit is contained in:
Erik 2015-03-04 19:52:20 -05:00
parent 95d50ec8d3
commit 346edc7b53
2 changed files with 46 additions and 22 deletions

View File

@ -34,6 +34,8 @@ extension String {
} }
} }
private typealias ProbeQueue = [() -> Void]
private enum PacketType: String { private enum PacketType: String {
case OPEN = "0" case OPEN = "0"
case CLOSE = "1" case CLOSE = "1"
@ -46,9 +48,11 @@ private enum PacketType: String {
class SocketEngine: NSObject, SRWebSocketDelegate { class SocketEngine: NSObject, SRWebSocketDelegate {
unowned let client:SocketIOClient unowned let client:SocketIOClient
private let pollingQueue = NSOperationQueue() private let workQueue = NSOperationQueue()
private var pingTimer:NSTimer? private var pingTimer:NSTimer?
private var _polling = true private var _polling = true
private var probing = false
private var probeWait = ProbeQueue()
private var wait = false private var wait = false
private var _websocket = false private var _websocket = false
private var websocketConnected = false private var websocketConnected = false
@ -141,7 +145,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
self.wait = true self.wait = true
NSURLConnection.sendAsynchronousRequest(req, NSURLConnection.sendAsynchronousRequest(req,
queue: self.pollingQueue) {[weak self] res, data, err in queue: self.workQueue) {[weak self] res, data, err in
if self == nil { if self == nil {
return return
} else if err != nil { } else if err != nil {
@ -172,7 +176,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
let reqPolling = NSURLRequest(URL: NSURL(string: urlPolling + "&t=\(time)-0&b64=1")!) let reqPolling = NSURLRequest(URL: NSURL(string: urlPolling + "&t=\(time)-0&b64=1")!)
NSURLConnection.sendAsynchronousRequest(reqPolling, NSURLConnection.sendAsynchronousRequest(reqPolling,
queue: self.pollingQueue) {[weak self] res, data, err in queue: self.workQueue) {[weak self] res, data, err in
var err:NSError? var err:NSError?
if self == nil { if self == nil {
return return
@ -209,7 +213,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
self?.ws = SRWebSocket(URL: self?.ws = SRWebSocket(URL:
NSURL(string: urlWebSocket + "&sid=\(self!.sid)")!) NSURL(string: urlWebSocket + "&sid=\(self!.sid)")!)
self?.ws?.delegate = self self?.ws?.delegate = self
// self?.ws?.open() self?.ws?.open()
} else { } else {
NSLog("Error handshaking") NSLog("Error handshaking")
return return
@ -340,16 +344,31 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
} }
} }
func send(msg:AnyObject) { func send(msg:AnyObject, datas:[NSData]? = nil) {
if self.websocket { let _send = {[weak self] (msg:AnyObject, datas:[NSData]?) -> () -> Void in
if !(msg is NSData) { return {
self.ws?.send("\(PacketType.MESSAGE.rawValue)\(msg)") if self == nil {
} else { return
let (data, nilString) = self.createBinaryDataForSend(msg as NSData) }
self.ws?.send(data!)
if self!.websocket {
self?.ws?.send("\(PacketType.MESSAGE.rawValue)\(msg)")
if datas != nil {
for data in datas! {
let (data, nilString) = self!.createBinaryDataForSend(data)
self?.ws?.send(data!)
}
}
} else {
self?.sendPollMessage(msg)
}
} }
}
if self.probing {
self.probeWait.append(_send(msg, datas))
} else { } else {
self.sendPollMessage(msg) _send(msg, datas)()
} }
} }
@ -370,7 +389,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
req.HTTPBody = postData req.HTTPBody = postData
NSURLConnection.sendAsynchronousRequest(req, NSURLConnection.sendAsynchronousRequest(req,
queue: self.pollingQueue) {[weak self] res, data, err in queue: self.workQueue) {[weak self] res, data, err in
if self == nil { if self == nil {
return return
} else if err != nil { } else if err != nil {
@ -385,6 +404,8 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
} }
func sendPollMessage(msg:AnyObject) { func sendPollMessage(msg:AnyObject) {
// println("Sending: \(msg)")
var postData:NSData var postData:NSData
let time = Int(NSDate().timeIntervalSince1970) let time = Int(NSDate().timeIntervalSince1970)
var req = NSMutableURLRequest(URL: var req = NSMutableURLRequest(URL:
@ -415,7 +436,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length") req.setValue(String(postData.length), forHTTPHeaderField: "Content-Length")
req.HTTPBody = postData req.HTTPBody = postData
NSURLConnection.sendAsynchronousRequest(req, queue: self.pollingQueue) {[weak self] res, data, err in NSURLConnection.sendAsynchronousRequest(req, queue: self.workQueue) {[weak self] res, data, err in
if err != nil { if err != nil {
println(err) println(err)
return return
@ -438,9 +459,15 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
private func upgradeTransport() { private func upgradeTransport() {
if self.websocketConnected { if self.websocketConnected {
self.probing = false
self._websocket = true self._websocket = true
self._polling = false self._polling = false
self.ws?.send(PacketType.UPGRADE.rawValue) self.ws?.send(PacketType.UPGRADE.rawValue)
for sender in self.probeWait {
sender()
}
self.probeWait.removeAll(keepCapacity: false)
} }
} }
@ -454,12 +481,14 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
// Called when the socket is opened // Called when the socket is opened
func webSocketDidOpen(webSocket:SRWebSocket!) { func webSocketDidOpen(webSocket:SRWebSocket!) {
self.websocketConnected = true self.websocketConnected = true
self.probing = true
self.probeWebSocket() self.probeWebSocket()
} }
// Called when the socket is closed // Called when the socket is closed
func webSocket(webSocket:SRWebSocket!, didCloseWithCode code:Int, reason:String!, wasClean:Bool) { func webSocket(webSocket:SRWebSocket!, didCloseWithCode code:Int, reason:String!, wasClean:Bool) {
self.websocketConnected = false self.websocketConnected = false
self.probing = false
self._websocket = false self._websocket = false
self._polling = true self._polling = true
@ -471,6 +500,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
self.websocketConnected = false self.websocketConnected = false
self._websocket = false self._websocket = false
self._polling = true self._polling = true
self.probing = false
self.client.webSocketDidFailWithError(error) self.client.webSocketDidFailWithError(error)
} }

View File

@ -171,10 +171,7 @@ class SocketIOClient {
hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp, wantsAck: self.currentAck) hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp, wantsAck: self.currentAck)
} }
self.engine?.send(str) self.engine?.send(str, datas: emitDatas)
for data in emitDatas {
self.engine?.send(data)
}
} else { } else {
if !ack { if !ack {
str = SocketEvent.createMessageForEvent(event, withArgs: items, hasBinary: false, str = SocketEvent.createMessageForEvent(event, withArgs: items, hasBinary: false,
@ -217,10 +214,7 @@ class SocketIOClient {
withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count) withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count)
} }
self?.engine?.send(str) self?.engine?.send(str, datas: emitDatas)
for data in emitDatas {
self?.engine?.send(data)
}
} }
} }
} }