move more things to socketengine. reconnecting broken

This commit is contained in:
Erik 2015-03-03 22:13:28 -05:00
parent 5cc42be709
commit 7e0549611f
3 changed files with 80 additions and 82 deletions

View File

@ -55,7 +55,14 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
self.client = client self.client = client
} }
func open(opts:[String: AnyObject]? = nil) { func close() {
if websocketConnected {
self.ws?.send(PacketType.MESSAGE.rawValue + PacketType.CLOSE.rawValue)
self.ws?.close()
}
}
private func createURLs(params:[String: AnyObject]? = nil) -> (NSURL, NSURL) {
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
@ -68,7 +75,31 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
urlWebSocket = "ws://" + url + "websocket" urlWebSocket = "ws://" + url + "websocket"
} }
let reqPolling = NSURLRequest(URL: NSURL(string: urlPolling)!) if params != nil {
for (key, value) in params! {
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
NSCharacterSet.URLHostAllowedCharacterSet())!
urlPolling += "&\(keyEsc)="
urlWebSocket += "&\(keyEsc)="
if value is String {
let valueEsc = (value as String).stringByAddingPercentEncodingWithAllowedCharacters(
NSCharacterSet.URLHostAllowedCharacterSet())!
urlPolling += "\(valueEsc)"
urlWebSocket += "\(valueEsc)"
} else {
urlPolling += "\(value)"
urlWebSocket += "\(value)"
}
}
}
return (NSURL(string: urlPolling)!, NSURL(string: urlWebSocket)!)
}
func open(opts:[String: AnyObject]? = nil) {
let (urlPolling, urlWebSocket) = self.createURLs(params: opts)
let reqPolling = NSURLRequest(URL: urlPolling)
NSURLConnection.sendAsynchronousRequest(reqPolling, queue: self.pollingQueue) {[weak self] res, data, err in NSURLConnection.sendAsynchronousRequest(reqPolling, queue: self.pollingQueue) {[weak self] res, data, err in
var err:NSError? var err:NSError?
@ -87,7 +118,7 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
if let sid = json["sid"] as? String { if let sid = json["sid"] as? String {
self?.sid = sid self?.sid = sid
self?.ws = SRWebSocket(URL: NSURL(string: urlWebSocket + "&sid=\(self!.sid)")!) self?.ws = SRWebSocket(URL: urlWebSocket.URLByAppendingPathComponent("&sid=\(self!.sid)"))
self?.ws?.delegate = self self?.ws?.delegate = self
self?.ws?.open() self?.ws?.open()
@ -140,6 +171,18 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
} }
} }
func send(msg:AnyObject) {
if self.websocketConnected {
if !(msg is NSData) {
self.ws?.send("\(PacketType.MESSAGE.rawValue)\(msg)")
} else {
self.ws?.send(msg)
}
} else {
// TODO handle polling
}
}
func sendPing() { func sendPing() {
if self.websocketConnected { if self.websocketConnected {
self.ws?.send(PacketType.PING.rawValue) self.ws?.send(PacketType.PING.rawValue)
@ -184,11 +227,17 @@ class SocketEngine: NSObject, SRWebSocketDelegate {
println("socket closed") println("socket closed")
self.pingTimer?.invalidate() self.pingTimer?.invalidate()
self.websocketConnected = false self.websocketConnected = false
// Temp
self.client.webSocket(webSocket, didCloseWithCode: code, reason: reason, wasClean: wasClean)
} }
// Called when an error occurs. // Called when an error occurs.
func webSocket(webSocket:SRWebSocket!, didFailWithError error:NSError!) { func webSocket(webSocket:SRWebSocket!, didFailWithError error:NSError!) {
self.pingTimer?.invalidate() self.pingTimer?.invalidate()
self.websocketConnected = false self.websocketConnected = false
// Temp
self.client.webSocket(webSocket, didFailWithError: error)
} }
} }

View File

@ -74,29 +74,29 @@ class SocketEvent {
if !hasBinary { if !hasBinary {
if nsp == nil { if nsp == nil {
if ack == nil { if ack == nil {
message = "42[\"\(event)\"" message = "2[\"\(event)\""
} else { } else {
message = "42\(ack!)[\"\(event)\"" message = "2\(ack!)[\"\(event)\""
} }
} else { } else {
if ack == nil { if ack == nil {
message = "42/\(nsp!),[\"\(event)\"" message = "2/\(nsp!),[\"\(event)\""
} else { } else {
message = "42/\(nsp!),\(ack!)[\"\(event)\"" message = "2/\(nsp!),\(ack!)[\"\(event)\""
} }
} }
} else { } else {
if nsp == nil { if nsp == nil {
if ack == nil { if ack == nil {
message = "45\(datas)-[\"\(event)\"" message = "5\(datas)-[\"\(event)\""
} else { } else {
message = "45\(datas)-\(ack!)[\"\(event)\"" message = "5\(datas)-\(ack!)[\"\(event)\""
} }
} else { } else {
if ack == nil { if ack == nil {
message = "45\(datas)-/\(nsp!),[\"\(event)\"" message = "5\(datas)-/\(nsp!),[\"\(event)\""
} else { } else {
message = "45\(datas)-/\(nsp!),\(ack!)[\"\(event)\"" message = "5\(datas)-/\(nsp!),\(ack!)[\"\(event)\""
} }
} }
} }
@ -110,15 +110,15 @@ class SocketEvent {
if ackType == 3 { if ackType == 3 {
if nsp == "/" { if nsp == "/" {
msg = "43\(ack)[" msg = "3\(ack)["
} else { } else {
msg = "43/\(nsp),\(ack)[" msg = "3/\(nsp),\(ack)["
} }
} else { } else {
if nsp == "/" { if nsp == "/" {
msg = "46\(binary)-\(ack)[" msg = "6\(binary)-\(ack)["
} else { } else {
msg = "46\(binary)-/\(nsp),\(ack)[" msg = "6\(binary)-/\(nsp),\(ack)["
} }
} }
@ -159,6 +159,7 @@ class SocketEvent {
if message != "" { if message != "" {
message.removeAtIndex(message.endIndex.predecessor()) message.removeAtIndex(message.endIndex.predecessor())
} }
return message + "]" return message + "]"
} }

View File

@ -24,7 +24,7 @@
import Foundation import Foundation
class SocketIOClient: NSObject, SRWebSocketDelegate { class SocketIOClient: NSObject {
let engine:SocketEngine! let engine:SocketEngine!
let socketURL:NSMutableString! let socketURL:NSMutableString!
let ackQueue = dispatch_queue_create("ackQueue".cStringUsingEncoding(NSUTF8StringEncoding), let ackQueue = dispatch_queue_create("ackQueue".cStringUsingEncoding(NSUTF8StringEncoding),
@ -44,7 +44,6 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
var closed = false var closed = false
var connected = false var connected = false
var connecting = false var connecting = false
var io:SRWebSocket?
var nsp:String? var nsp:String?
var reconnects = true var reconnects = true
var reconnecting = false var reconnecting = false
@ -97,49 +96,20 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
self.closed = true self.closed = true
self.connecting = false self.connecting = false
self.connected = false self.connected = false
self.io?.send("41") self.engine?.close()
self.io?.close()
} }
// Connects to the server // Connects to the server
func connect() { func connect() {
self.connectWithURL(self.createConnectURL()) self.engine.open()
} }
// Connect to the server using params // Connect to the server using params
func connectWithParams(params:[String: AnyObject]) { func connectWithParams(params:[String: AnyObject]) {
self.params = params self.params = params
self.paramConnect = true self.paramConnect = true
var endpoint = self.createConnectURL()
for (key, value) in params { self.engine.open(opts: params)
let keyEsc = key.stringByAddingPercentEncodingWithAllowedCharacters(
NSCharacterSet.URLHostAllowedCharacterSet())!
endpoint += "&\(keyEsc)="
if value is String {
let valueEsc = (value as String).stringByAddingPercentEncodingWithAllowedCharacters(
NSCharacterSet.URLHostAllowedCharacterSet())!
endpoint += "\(valueEsc)"
} else {
endpoint += "\(value)"
}
}
self.connectWithURL(endpoint)
}
private func connectWithURL(url:String) {
if self.closed {
println("Warning: This socket was previvously closed. Reopening could be dangerous. Be careful.")
}
self.connecting = true
self.closed = false
self.io = SRWebSocket(URL: NSURL(string: url))
self.io?.delegate = self
self.io?.open()
} }
// Creates a binary message, ready for sending // Creates a binary message, ready for sending
@ -151,14 +121,6 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
return mutData return mutData
} }
private func createConnectURL() -> String {
if self._secure {
return "wss://\(self.socketURL)/socket.io/?transport=websocket"
} else {
return "ws://\(self.socketURL)/socket.io/?transport=websocket"
}
}
// Sends a message with multiple args // Sends a message with multiple args
// If a message contains binary we have to send those // If a message contains binary we have to send those
// seperately. // seperately.
@ -215,9 +177,9 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp, wantsAck: self.currentAck) hasBinary: true, withDatas: emitDatas.count, toNamespace: self.nsp, wantsAck: self.currentAck)
} }
self.io?.send(str) self.engine?.send(str)
for data in emitDatas { for data in emitDatas {
self.io?.send(data) self.engine?.send(data)
} }
} else { } else {
if !ack { if !ack {
@ -228,7 +190,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
withDatas: 0, toNamespace: self.nsp, wantsAck: self.currentAck) withDatas: 0, toNamespace: self.nsp, wantsAck: self.currentAck)
} }
self.io?.send(str) self.engine?.send(str)
} }
} }
@ -251,7 +213,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
withAckType: 3, withNsp: self!.nsp!) withAckType: 3, withNsp: self!.nsp!)
} }
self?.io?.send(str) self?.engine?.send(str)
} else { } else {
if self?.nsp == nil { if self?.nsp == nil {
str = SocketEvent.createAck(ack, withArgs: items, str = SocketEvent.createAck(ack, withArgs: items,
@ -261,9 +223,9 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count) withAckType: 6, withNsp: self!.nsp!, withBinary: emitDatas.count)
} }
self?.io?.send(str) self?.engine?.send(str)
for data in emitDatas { for data in emitDatas {
self?.io?.send(data) self?.engine?.send(data)
} }
} }
} }
@ -321,9 +283,10 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
} }
} }
// Should be removed and moved to SocketEngine
func joinNamespace() { func joinNamespace() {
if self.nsp != nil { if self.nsp != nil {
self.io?.send("40/\(self.nsp!)") self.engine?.send("0/\(self.nsp!)")
} }
} }
@ -579,7 +542,6 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
data = messageInternals[2] data = messageInternals[2]
} }
println(data)
// 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) {
@ -632,7 +594,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
} }
if nsp == "" { if nsp == "" {
ackNum = String(arr[2...arr.count-1]) ackNum = String(arr[1...arr.count-1])
} else { } else {
ackNum = messageGroups[3] ackNum = messageGroups[3]
} }
@ -694,7 +656,7 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
ackNum = "" ackNum = ""
} }
numberOfPlaceholders = (messageType["45"] ~= "") as String numberOfPlaceholders = (messageType["5"] ~= "") as String
event = (RegexMutable(binaryGroup[4])["\""] ~= "") as String event = (RegexMutable(binaryGroup[4])["\""] ~= "") as String
mutMessageObject = RegexMutable(binaryGroup[5]) mutMessageObject = RegexMutable(binaryGroup[5])
@ -787,20 +749,6 @@ class SocketIOClient: NSObject, SRWebSocketDelegate {
} }
} }
func sendPing() {
if self.connected {
self.io?.send("2")
}
}
// Starts the ping timer
private func startPingTimer(#interval:Int) {
dispatch_async(dispatch_get_main_queue()) {
self.pingTimer = NSTimer.scheduledTimerWithTimeInterval(NSTimeInterval(interval), target: self,
selector: Selector("sendPing"), userInfo: nil, repeats: true)
}
}
// We lost connection and should attempt to reestablish // We lost connection and should attempt to reestablish
private func tryReconnect(var #triesLeft:Int) { private func tryReconnect(var #triesLeft:Int) {
if triesLeft != -1 && triesLeft <= 0 { if triesLeft != -1 && triesLeft <= 0 {