Support both v2 and v3
This commit is contained in:
parent
21290f5752
commit
fde88c10c5
@ -134,6 +134,18 @@ open class SocketIOClient: NSObject, SocketIOClientSpec {
|
|||||||
|
|
||||||
joinNamespace(withPayload: payload)
|
joinNamespace(withPayload: payload)
|
||||||
|
|
||||||
|
switch manager.version {
|
||||||
|
case .three:
|
||||||
|
break
|
||||||
|
case .two where manager.status == .connected && nsp == "/":
|
||||||
|
// We might not get a connect event for the default nsp, fire immediately
|
||||||
|
didConnect(toNamespace: nsp, payload: nil)
|
||||||
|
|
||||||
|
return
|
||||||
|
case _:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
guard timeoutAfter != 0 else { return }
|
guard timeoutAfter != 0 else { return }
|
||||||
|
|
||||||
manager.handleQueue.asyncAfter(deadline: DispatchTime.now() + timeoutAfter) {[weak self] in
|
manager.handleQueue.asyncAfter(deadline: DispatchTime.now() + timeoutAfter) {[weak self] in
|
||||||
|
|||||||
@ -25,6 +25,12 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Starscream
|
import Starscream
|
||||||
|
|
||||||
|
/// The socket.io version being used.
|
||||||
|
public enum SocketIOVersion: Int {
|
||||||
|
case two = 2
|
||||||
|
case three = 3
|
||||||
|
}
|
||||||
|
|
||||||
protocol ClientOption : CustomStringConvertible, Equatable {
|
protocol ClientOption : CustomStringConvertible, Equatable {
|
||||||
func getSocketIOOptionValue() -> Any
|
func getSocketIOOptionValue() -> Any
|
||||||
}
|
}
|
||||||
@ -99,6 +105,9 @@ public enum SocketIOClientOption : ClientOption {
|
|||||||
/// Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs.
|
/// Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs.
|
||||||
case sessionDelegate(URLSessionDelegate)
|
case sessionDelegate(URLSessionDelegate)
|
||||||
|
|
||||||
|
/// The version of socket.io being used. This should match the server version. Default is 3.
|
||||||
|
case version(SocketIOVersion)
|
||||||
|
|
||||||
// MARK: Properties
|
// MARK: Properties
|
||||||
|
|
||||||
/// The description of this option.
|
/// The description of this option.
|
||||||
@ -148,6 +157,8 @@ public enum SocketIOClientOption : ClientOption {
|
|||||||
description = "sessionDelegate"
|
description = "sessionDelegate"
|
||||||
case .enableSOCKSProxy:
|
case .enableSOCKSProxy:
|
||||||
description = "enableSOCKSProxy"
|
description = "enableSOCKSProxy"
|
||||||
|
case .version:
|
||||||
|
description = "version"
|
||||||
}
|
}
|
||||||
|
|
||||||
return description
|
return description
|
||||||
@ -199,6 +210,8 @@ public enum SocketIOClientOption : ClientOption {
|
|||||||
value = delegate
|
value = delegate
|
||||||
case let .enableSOCKSProxy(enable):
|
case let .enableSOCKSProxy(enable):
|
||||||
value = enable
|
value = enable
|
||||||
|
case let.version(versionNum):
|
||||||
|
value = versionNum
|
||||||
}
|
}
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|||||||
@ -111,6 +111,9 @@ open class SocketEngine:
|
|||||||
/// The url for WebSockets.
|
/// The url for WebSockets.
|
||||||
public private(set) var urlWebSocket = URL(string: "http://localhost/")!
|
public private(set) var urlWebSocket = URL(string: "http://localhost/")!
|
||||||
|
|
||||||
|
/// The version of engine.io being used. Default is three.
|
||||||
|
public private(set) var version: SocketIOVersion = .three
|
||||||
|
|
||||||
/// If `true`, then the engine is currently in WebSockets mode.
|
/// If `true`, then the engine is currently in WebSockets mode.
|
||||||
@available(*, deprecated, message: "No longer needed, if we're not polling, then we must be doing websockets")
|
@available(*, deprecated, message: "No longer needed, if we're not polling, then we must be doing websockets")
|
||||||
public private(set) var websocket = false
|
public private(set) var websocket = false
|
||||||
@ -133,8 +136,14 @@ open class SocketEngine:
|
|||||||
|
|
||||||
private var lastCommunication: Date?
|
private var lastCommunication: Date?
|
||||||
private var pingInterval: Int?
|
private var pingInterval: Int?
|
||||||
private var pingTimeout = 0
|
private var pingTimeout = 0 {
|
||||||
|
didSet {
|
||||||
|
pongsMissedMax = Int(pingTimeout / (pingInterval ?? 25000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var pongsMissed = 0
|
||||||
|
private var pongsMissedMax = 0
|
||||||
private var probeWait = ProbeWaitQueue()
|
private var probeWait = ProbeWaitQueue()
|
||||||
private var secure = false
|
private var secure = false
|
||||||
private var certPinner: CertificatePinning?
|
private var certPinner: CertificatePinning?
|
||||||
@ -196,8 +205,9 @@ open class SocketEngine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func handleBase64(message: String) {
|
private func handleBase64(message: String) {
|
||||||
|
let offset = version.rawValue >= 3 ? 1 : 2
|
||||||
// binary in base64 string
|
// binary in base64 string
|
||||||
let noPrefix = String(message[message.index(message.startIndex, offsetBy: 1)..<message.endIndex])
|
let noPrefix = String(message[message.index(message.startIndex, offsetBy: offset)..<message.endIndex])
|
||||||
|
|
||||||
if let data = Data(base64Encoded: noPrefix, options: .ignoreUnknownCharacters) {
|
if let data = Data(base64Encoded: noPrefix, options: .ignoreUnknownCharacters) {
|
||||||
client?.parseEngineBinaryData(data)
|
client?.parseEngineBinaryData(data)
|
||||||
@ -278,6 +288,14 @@ open class SocketEngine:
|
|||||||
urlWebSocket.percentEncodedQuery = "transport=websocket" + queryString
|
urlWebSocket.percentEncodedQuery = "transport=websocket" + queryString
|
||||||
urlPolling.percentEncodedQuery = "transport=polling&b64=1" + queryString
|
urlPolling.percentEncodedQuery = "transport=polling&b64=1" + queryString
|
||||||
|
|
||||||
|
if !urlWebSocket.percentEncodedQuery!.contains("EIO") {
|
||||||
|
urlWebSocket.percentEncodedQuery = urlWebSocket.percentEncodedQuery! + engineIOParam
|
||||||
|
}
|
||||||
|
|
||||||
|
if !urlPolling.percentEncodedQuery!.contains("EIO") {
|
||||||
|
urlPolling.percentEncodedQuery = urlPolling.percentEncodedQuery! + engineIOParam
|
||||||
|
}
|
||||||
|
|
||||||
return (urlPolling.url!, urlWebSocket.url!)
|
return (urlPolling.url!, urlWebSocket.url!)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +307,8 @@ open class SocketEngine:
|
|||||||
includingCookies: session?.configuration.httpCookieStorage?.cookies(for: urlPollingWithSid)
|
includingCookies: session?.configuration.httpCookieStorage?.cookies(for: urlPollingWithSid)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
print("ws req: \(req)")
|
||||||
|
|
||||||
ws = WebSocket(request: req, certPinner: certPinner, compressionHandler: compress ? WSCompression() : nil)
|
ws = WebSocket(request: req, certPinner: certPinner, compressionHandler: compress ? WSCompression() : nil)
|
||||||
ws?.callbackQueue = engineQueue
|
ws?.callbackQueue = engineQueue
|
||||||
ws?.delegate = self
|
ws?.delegate = self
|
||||||
@ -413,6 +433,7 @@ open class SocketEngine:
|
|||||||
|
|
||||||
self.sid = sid
|
self.sid = sid
|
||||||
connected = true
|
connected = true
|
||||||
|
pongsMissed = 0
|
||||||
|
|
||||||
if let upgrades = json["upgrades"] as? [String] {
|
if let upgrades = json["upgrades"] as? [String] {
|
||||||
upgradeWs = upgrades.contains("websocket")
|
upgradeWs = upgrades.contains("websocket")
|
||||||
@ -429,15 +450,22 @@ open class SocketEngine:
|
|||||||
createWebSocketAndConnect()
|
createWebSocketAndConnect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if version.rawValue >= 3 {
|
||||||
|
checkPings()
|
||||||
|
} else {
|
||||||
|
sendPing()
|
||||||
|
}
|
||||||
|
|
||||||
if !forceWebsockets {
|
if !forceWebsockets {
|
||||||
doPoll()
|
doPoll()
|
||||||
}
|
}
|
||||||
|
|
||||||
checkPings()
|
|
||||||
client?.engineDidOpen(reason: "Connect")
|
client?.engineDidOpen(reason: "Connect")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handlePong(with message: String) {
|
private func handlePong(with message: String) {
|
||||||
|
pongsMissed = 0
|
||||||
|
|
||||||
// We should upgrade
|
// We should upgrade
|
||||||
if message == "3probe" {
|
if message == "3probe" {
|
||||||
DefaultSocketLogger.Logger.log("Received probe response, should upgrade to WebSockets",
|
DefaultSocketLogger.Logger.log("Received probe response, should upgrade to WebSockets",
|
||||||
@ -445,10 +473,14 @@ open class SocketEngine:
|
|||||||
|
|
||||||
upgradeTransport()
|
upgradeTransport()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
client?.engineDidReceivePong()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handlePing(with message: String) {
|
private func handlePing(with message: String) {
|
||||||
|
if version.rawValue >= 3 {
|
||||||
write("", withType: .pong, withData: [])
|
write("", withType: .pong, withData: [])
|
||||||
|
}
|
||||||
|
|
||||||
client?.engineDidReceivePing()
|
client?.engineDidReceivePing()
|
||||||
}
|
}
|
||||||
@ -478,7 +510,7 @@ open class SocketEngine:
|
|||||||
|
|
||||||
lastCommunication = Date()
|
lastCommunication = Date()
|
||||||
|
|
||||||
client?.parseEngineBinaryData(data)
|
client?.parseEngineBinaryData(version.rawValue >= 3 ? data : data.subdata(in: 1..<data.endIndex))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses a raw engine.io packet.
|
/// Parses a raw engine.io packet.
|
||||||
@ -489,13 +521,11 @@ open class SocketEngine:
|
|||||||
|
|
||||||
DefaultSocketLogger.Logger.log("Got message: \(message)", type: SocketEngine.logType)
|
DefaultSocketLogger.Logger.log("Got message: \(message)", type: SocketEngine.logType)
|
||||||
|
|
||||||
let reader = SocketStringReader(message: message)
|
if message.hasPrefix(version.rawValue >= 3 ? "b" : "b4") {
|
||||||
|
|
||||||
if message.hasPrefix("b") {
|
|
||||||
return handleBase64(message: message)
|
return handleBase64(message: message)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let type = SocketEnginePacketType(rawValue: Int(reader.currentCharacter) ?? -1) else {
|
guard let type = SocketEnginePacketType(rawValue: message.first?.wholeNumberValue ?? -1) else {
|
||||||
checkAndHandleEngineError(message)
|
checkAndHandleEngineError(message)
|
||||||
|
|
||||||
return
|
return
|
||||||
@ -536,6 +566,34 @@ open class SocketEngine:
|
|||||||
waitingForPost = false
|
waitingForPost = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func sendPing() {
|
||||||
|
guard connected, let pingInterval = pingInterval else {
|
||||||
|
print("not connected \(self.connected) or no ping interval \(self.pingInterval ?? -222)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Server is not responding
|
||||||
|
if pongsMissed > pongsMissedMax {
|
||||||
|
closeOutEngine(reason: "Ping timeout")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pongsMissed += 1
|
||||||
|
write("", withType: .ping, withData: [], completion: nil)
|
||||||
|
|
||||||
|
engineQueue.asyncAfter(deadline: .now() + .milliseconds(pingInterval)) {[weak self, id = self.sid] in
|
||||||
|
// Make sure not to ping old connections
|
||||||
|
guard let this = self, this.sid == id else {
|
||||||
|
print("wrong ping?")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.sendPing()
|
||||||
|
}
|
||||||
|
|
||||||
|
client?.engineDidSendPing()
|
||||||
|
}
|
||||||
|
|
||||||
/// Called when the engine should set/update its configs from a given configuration.
|
/// Called when the engine should set/update its configs from a given configuration.
|
||||||
///
|
///
|
||||||
/// parameter config: The `SocketIOClientConfiguration` that should be used to set/update configs.
|
/// parameter config: The `SocketIOClientConfiguration` that should be used to set/update configs.
|
||||||
@ -570,6 +628,8 @@ open class SocketEngine:
|
|||||||
self.compress = true
|
self.compress = true
|
||||||
case .enableSOCKSProxy:
|
case .enableSOCKSProxy:
|
||||||
self.enableSOCKSProxy = true
|
self.enableSOCKSProxy = true
|
||||||
|
case let .version(num):
|
||||||
|
version = num
|
||||||
default:
|
default:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,10 +44,16 @@ import Foundation
|
|||||||
/// - parameter reason: The reason the engine opened.
|
/// - parameter reason: The reason the engine opened.
|
||||||
func engineDidOpen(reason: String)
|
func engineDidOpen(reason: String)
|
||||||
|
|
||||||
/// Called when the engine receives a ping message.
|
/// Called when the engine receives a ping message. Only called in socket.io >3.
|
||||||
func engineDidReceivePing()
|
func engineDidReceivePing()
|
||||||
|
|
||||||
/// Called when the engine sends a pong to the server.
|
/// Called when the engine receives a pong message. Only called in socket.io 2.
|
||||||
|
func engineDidReceivePong()
|
||||||
|
|
||||||
|
/// Called when the engine sends a ping to the server. Only called in socket.io 2.
|
||||||
|
func engineDidSendPing()
|
||||||
|
|
||||||
|
/// Called when the engine sends a pong to the server. Only called in socket.io >3.
|
||||||
func engineDidSendPong()
|
func engineDidSendPong()
|
||||||
|
|
||||||
/// Called when the engine has a message that must be parsed.
|
/// Called when the engine has a message that must be parsed.
|
||||||
|
|||||||
@ -79,7 +79,15 @@ extension SocketEnginePollable {
|
|||||||
postWait.removeAll(keepingCapacity: true)
|
postWait.removeAll(keepingCapacity: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
let postStr = postWait.lazy.map({ $0.msg }).joined(separator: "\u{1e}")
|
var postStr = ""
|
||||||
|
|
||||||
|
if version.rawValue >= 3 {
|
||||||
|
postStr = postWait.lazy.map({ $0.msg }).joined(separator: "\u{1e}")
|
||||||
|
} else {
|
||||||
|
for packet in postWait {
|
||||||
|
postStr += "\(packet.msg.utf16.count):\(packet.msg)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DefaultSocketLogger.Logger.log("Created POST string: \(postStr)", type: "SocketEnginePolling")
|
DefaultSocketLogger.Logger.log("Created POST string: \(postStr)", type: "SocketEnginePolling")
|
||||||
|
|
||||||
@ -195,11 +203,30 @@ extension SocketEnginePollable {
|
|||||||
|
|
||||||
DefaultSocketLogger.Logger.log("Got poll message: \(str)", type: "SocketEnginePolling")
|
DefaultSocketLogger.Logger.log("Got poll message: \(str)", type: "SocketEnginePolling")
|
||||||
|
|
||||||
|
if version.rawValue >= 3 {
|
||||||
let records = str.components(separatedBy: "\u{1e}")
|
let records = str.components(separatedBy: "\u{1e}")
|
||||||
|
|
||||||
for record in records {
|
for record in records {
|
||||||
parseEngineMessage(record)
|
parseEngineMessage(record)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
guard str.count != 1 else {
|
||||||
|
parseEngineMessage(str)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var reader = SocketStringReader(message: str)
|
||||||
|
|
||||||
|
while reader.hasNext {
|
||||||
|
if let n = Int(reader.readUntilOccurence(of: ":")) {
|
||||||
|
parseEngineMessage(reader.read(count: n))
|
||||||
|
} else {
|
||||||
|
parseEngineMessage(str)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sends an engine.io message through the polling transport.
|
/// Sends an engine.io message through the polling transport.
|
||||||
|
|||||||
@ -81,6 +81,9 @@ public protocol SocketEngineSpec: class {
|
|||||||
/// The url for WebSockets.
|
/// The url for WebSockets.
|
||||||
var urlWebSocket: URL { get }
|
var urlWebSocket: URL { get }
|
||||||
|
|
||||||
|
/// The version of engine.io being used. Default is three.
|
||||||
|
var version: SocketIOVersion { get }
|
||||||
|
|
||||||
/// If `true`, then the engine is currently in WebSockets mode.
|
/// If `true`, then the engine is currently in WebSockets mode.
|
||||||
@available(*, deprecated, message: "No longer needed, if we're not polling, then we must be doing websockets")
|
@available(*, deprecated, message: "No longer needed, if we're not polling, then we must be doing websockets")
|
||||||
var websocket: Bool { get }
|
var websocket: Bool { get }
|
||||||
@ -142,10 +145,23 @@ public protocol SocketEngineSpec: class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension SocketEngineSpec {
|
extension SocketEngineSpec {
|
||||||
|
var engineIOParam: String {
|
||||||
|
switch version {
|
||||||
|
case .two:
|
||||||
|
return "&EIO=3"
|
||||||
|
case .three:
|
||||||
|
return "&EIO=4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var urlPollingWithSid: URL {
|
var urlPollingWithSid: URL {
|
||||||
var com = URLComponents(url: urlPolling, resolvingAgainstBaseURL: false)!
|
var com = URLComponents(url: urlPolling, resolvingAgainstBaseURL: false)!
|
||||||
com.percentEncodedQuery = com.percentEncodedQuery! + "&sid=\(sid.urlEncode()!)"
|
com.percentEncodedQuery = com.percentEncodedQuery! + "&sid=\(sid.urlEncode()!)"
|
||||||
|
|
||||||
|
if !com.percentEncodedQuery!.contains("EIO") {
|
||||||
|
com.percentEncodedQuery = com.percentEncodedQuery! + engineIOParam
|
||||||
|
}
|
||||||
|
|
||||||
return com.url!
|
return com.url!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +169,11 @@ extension SocketEngineSpec {
|
|||||||
var com = URLComponents(url: urlWebSocket, resolvingAgainstBaseURL: false)!
|
var com = URLComponents(url: urlWebSocket, resolvingAgainstBaseURL: false)!
|
||||||
com.percentEncodedQuery = com.percentEncodedQuery! + (sid == "" ? "" : "&sid=\(sid.urlEncode()!)")
|
com.percentEncodedQuery = com.percentEncodedQuery! + (sid == "" ? "" : "&sid=\(sid.urlEncode()!)")
|
||||||
|
|
||||||
|
if !com.percentEncodedQuery!.contains("EIO") {
|
||||||
|
com.percentEncodedQuery = com.percentEncodedQuery! + engineIOParam
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return com.url!
|
return com.url!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,10 +193,12 @@ extension SocketEngineSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createBinaryDataForSend(using data: Data) -> Either<Data, String> {
|
func createBinaryDataForSend(using data: Data) -> Either<Data, String> {
|
||||||
|
let prefixB64 = version.rawValue >= 3 ? "b" : "b4"
|
||||||
|
|
||||||
if polling {
|
if polling {
|
||||||
return .right("b" + data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)))
|
return .right(prefixB64 + data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)))
|
||||||
} else {
|
} else {
|
||||||
return .left(data)
|
return .left(version.rawValue >= 3 ? data : Data([0x4]) + data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -119,6 +119,8 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public private(set) var version = SocketIOVersion.three
|
||||||
|
|
||||||
/// A list of packets that are waiting for binary data.
|
/// A list of packets that are waiting for binary data.
|
||||||
///
|
///
|
||||||
/// The way that socket.io works all data should be sent directly after each packet.
|
/// The way that socket.io works all data should be sent directly after each packet.
|
||||||
@ -214,7 +216,7 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
|
|||||||
|
|
||||||
var payloadStr = ""
|
var payloadStr = ""
|
||||||
|
|
||||||
if payload != nil,
|
if version.rawValue >= 3 && payload != nil,
|
||||||
let payloadData = try? JSONSerialization.data(withJSONObject: payload!, options: .fragmentsAllowed),
|
let payloadData = try? JSONSerialization.data(withJSONObject: payload!, options: .fragmentsAllowed),
|
||||||
let jsonString = String(data: payloadData, encoding: .utf8) {
|
let jsonString = String(data: payloadData, encoding: .utf8) {
|
||||||
payloadStr = jsonString
|
payloadStr = jsonString
|
||||||
@ -349,12 +351,20 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
|
|||||||
|
|
||||||
status = .connected
|
status = .connected
|
||||||
|
|
||||||
for (_, socket) in nsps where socket.status == .connecting {
|
if version.rawValue < 3 {
|
||||||
|
nsps["/"]?.didConnect(toNamespace: "/", payload: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (nsp, socket) in nsps where socket.status == .connecting {
|
||||||
|
if version.rawValue < 3 && nsp == "/" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
connectSocket(socket, withPayload: socket.connectPayload)
|
connectSocket(socket, withPayload: socket.connectPayload)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when the engine receives a pong message.
|
/// Called when the engine receives a ping message.
|
||||||
open func engineDidReceivePing() {
|
open func engineDidReceivePing() {
|
||||||
handleQueue.async {
|
handleQueue.async {
|
||||||
self._engineDidReceivePing()
|
self._engineDidReceivePing()
|
||||||
@ -366,6 +376,28 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Called when the sends a ping to the server.
|
/// Called when the sends a ping to the server.
|
||||||
|
open func engineDidSendPing() {
|
||||||
|
handleQueue.async {
|
||||||
|
self._engineDidSendPing()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func _engineDidSendPing() {
|
||||||
|
emitAll(clientEvent: .ping, data: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the engine receives a pong message.
|
||||||
|
open func engineDidReceivePong() {
|
||||||
|
handleQueue.async {
|
||||||
|
self._engineDidReceivePong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func _engineDidReceivePong() {
|
||||||
|
emitAll(clientEvent: .pong, data: [])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called when the sends a pong to the server.
|
||||||
open func engineDidSendPong() {
|
open func engineDidSendPong() {
|
||||||
handleQueue.async {
|
handleQueue.async {
|
||||||
self._engineDidSendPong()
|
self._engineDidSendPong()
|
||||||
@ -508,13 +540,13 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
|
|||||||
for option in config {
|
for option in config {
|
||||||
switch option {
|
switch option {
|
||||||
case let .forceNew(new):
|
case let .forceNew(new):
|
||||||
self.forceNew = new
|
forceNew = new
|
||||||
case let .handleQueue(queue):
|
case let .handleQueue(queue):
|
||||||
self.handleQueue = queue
|
handleQueue = queue
|
||||||
case let .reconnects(reconnects):
|
case let .reconnects(reconnects):
|
||||||
self.reconnects = reconnects
|
self.reconnects = reconnects
|
||||||
case let .reconnectAttempts(attempts):
|
case let .reconnectAttempts(attempts):
|
||||||
self.reconnectAttempts = attempts
|
reconnectAttempts = attempts
|
||||||
case let .reconnectWait(wait):
|
case let .reconnectWait(wait):
|
||||||
reconnectWait = abs(wait)
|
reconnectWait = abs(wait)
|
||||||
case let .reconnectWaitMax(wait):
|
case let .reconnectWaitMax(wait):
|
||||||
@ -525,6 +557,8 @@ open class SocketManager: NSObject, SocketManagerSpec, SocketParsable, SocketDat
|
|||||||
DefaultSocketLogger.Logger.log = log
|
DefaultSocketLogger.Logger.log = log
|
||||||
case let .logger(logger):
|
case let .logger(logger):
|
||||||
DefaultSocketLogger.Logger = logger
|
DefaultSocketLogger.Logger = logger
|
||||||
|
case let .version(num):
|
||||||
|
version = num
|
||||||
case _:
|
case _:
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,6 +83,9 @@ public protocol SocketManagerSpec : AnyObject, SocketEngineClient {
|
|||||||
/// The status of this manager.
|
/// The status of this manager.
|
||||||
var status: SocketIOStatus { get }
|
var status: SocketIOStatus { get }
|
||||||
|
|
||||||
|
/// The version of socket.io in use.
|
||||||
|
var version: SocketIOVersion { get }
|
||||||
|
|
||||||
// MARK: Methods
|
// MARK: Methods
|
||||||
|
|
||||||
/// Connects the underlying transport.
|
/// Connects the underlying transport.
|
||||||
|
|||||||
@ -10,6 +10,19 @@ import XCTest
|
|||||||
@testable import SocketIO
|
@testable import SocketIO
|
||||||
|
|
||||||
class SocketEngineTest: XCTestCase {
|
class SocketEngineTest: XCTestCase {
|
||||||
|
func testBasicPollingMessageV3() {
|
||||||
|
let expect = expectation(description: "Basic polling test v3")
|
||||||
|
|
||||||
|
socket.on("blankTest") {data, ack in
|
||||||
|
expect.fulfill()
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.setConfigs([.version(.two)])
|
||||||
|
engine.parsePollingMessage("15:42[\"blankTest\"]")
|
||||||
|
|
||||||
|
waitForExpectations(timeout: 3, handler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
func testBasicPollingMessage() {
|
func testBasicPollingMessage() {
|
||||||
let expect = expectation(description: "Basic polling test")
|
let expect = expectation(description: "Basic polling test")
|
||||||
socket.on("blankTest") {data, ack in
|
socket.on("blankTest") {data, ack in
|
||||||
@ -83,15 +96,15 @@ class SocketEngineTest: XCTestCase {
|
|||||||
"created": "2016-05-04T18:31:15+0200"
|
"created": "2016-05-04T18:31:15+0200"
|
||||||
]
|
]
|
||||||
|
|
||||||
XCTAssertEqual(engine.urlPolling.query, "transport=polling&b64=1&created=2016-05-04T18%3A31%3A15%2B0200")
|
XCTAssertEqual(engine.urlPolling.query, "transport=polling&b64=1&created=2016-05-04T18%3A31%3A15%2B0200&EIO=4")
|
||||||
XCTAssertEqual(engine.urlWebSocket.query, "transport=websocket&created=2016-05-04T18%3A31%3A15%2B0200")
|
XCTAssertEqual(engine.urlWebSocket.query, "transport=websocket&created=2016-05-04T18%3A31%3A15%2B0200&EIO=4")
|
||||||
|
|
||||||
engine.connectParams = [
|
engine.connectParams = [
|
||||||
"forbidden": "!*'();:@&=+$,/?%#[]\" {}^|"
|
"forbidden": "!*'();:@&=+$,/?%#[]\" {}^|"
|
||||||
]
|
]
|
||||||
|
|
||||||
XCTAssertEqual(engine.urlPolling.query, "transport=polling&b64=1&forbidden=%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D%22%20%7B%7D%5E%7C")
|
XCTAssertEqual(engine.urlPolling.query, "transport=polling&b64=1&forbidden=%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D%22%20%7B%7D%5E%7C&EIO=4")
|
||||||
XCTAssertEqual(engine.urlWebSocket.query, "transport=websocket&forbidden=%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D%22%20%7B%7D%5E%7C")
|
XCTAssertEqual(engine.urlWebSocket.query, "transport=websocket&forbidden=%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%25%23%5B%5D%22%20%7B%7D%5E%7C&EIO=4")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testBase64Data() {
|
func testBase64Data() {
|
||||||
|
|||||||
@ -485,6 +485,7 @@ class TestEngine: SocketEngineSpec {
|
|||||||
private(set) var urlWebSocket = URL(string: "http://localhost/")!
|
private(set) var urlWebSocket = URL(string: "http://localhost/")!
|
||||||
private(set) var websocket = false
|
private(set) var websocket = false
|
||||||
private(set) var ws: WebSocket? = nil
|
private(set) var ws: WebSocket? = nil
|
||||||
|
private(set) var version = SocketIOVersion.three
|
||||||
|
|
||||||
fileprivate var onConnect: (() -> ())?
|
fileprivate var onConnect: (() -> ())?
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user