more linux work
This commit is contained in:
parent
afc5a561d0
commit
95b3bfc802
@ -24,7 +24,11 @@
|
||||
|
||||
import Dispatch
|
||||
import Foundation
|
||||
#if !os(Linux)
|
||||
import StarscreamSocketIO
|
||||
#else
|
||||
import WebSockets
|
||||
#endif
|
||||
|
||||
/// The class that handles the engine.io protocol and transports.
|
||||
/// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods.
|
||||
@ -60,6 +64,9 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
/// **Do not touch this directly**
|
||||
public var waitingForPost = false
|
||||
|
||||
/// The WebSocket for this engine.
|
||||
public var ws: WebSocket?
|
||||
|
||||
/// `true` if this engine is closed.
|
||||
public private(set) var closed = false
|
||||
|
||||
@ -95,6 +102,17 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
/// If `true`, the engine is currently seeing whether it can upgrade to WebSockets.
|
||||
public private(set) var probing = false
|
||||
|
||||
/// Whether or not this engine uses secure transports
|
||||
public private(set) var secure = false
|
||||
|
||||
#if !os(Linux)
|
||||
/// A custom security validator for Starscream. Useful for SSL pinning.
|
||||
public private(set) var security: SSLSecurity?
|
||||
#endif
|
||||
|
||||
/// Whether or not to allow self signed certificates.
|
||||
public private(set) var selfSigned = false
|
||||
|
||||
/// The URLSession that will be used for polling.
|
||||
public private(set) var session: URLSession?
|
||||
|
||||
@ -113,9 +131,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
/// If `true`, then the engine is currently in WebSockets mode.
|
||||
public private(set) var websocket = false
|
||||
|
||||
/// The WebSocket for this engine.
|
||||
public private(set) var ws: WebSocket?
|
||||
|
||||
/// The client for this engine.
|
||||
public weak var client: SocketEngineClient?
|
||||
|
||||
@ -133,9 +148,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
private var pongsMissed = 0
|
||||
private var pongsMissedMax = 0
|
||||
private var probeWait = ProbeWaitQueue()
|
||||
private var secure = false
|
||||
private var security: SSLSecurity?
|
||||
private var selfSigned = false
|
||||
|
||||
// MARK: Initializers
|
||||
|
||||
@ -308,32 +320,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
return (urlPolling.url!, urlWebSocket.url!)
|
||||
}
|
||||
|
||||
private func createWebSocketAndConnect() {
|
||||
ws?.delegate = nil // TODO this seems a bit defensive, is this really needed?
|
||||
ws = WebSocket(url: urlWebSocketWithSid)
|
||||
|
||||
if cookies != nil {
|
||||
let headers = HTTPCookie.requestHeaderFields(with: cookies!)
|
||||
for (key, value) in headers {
|
||||
ws?.headers[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
if extraHeaders != nil {
|
||||
for (headerName, value) in extraHeaders! {
|
||||
ws?.headers[headerName] = value
|
||||
}
|
||||
}
|
||||
|
||||
ws?.callbackQueue = engineQueue
|
||||
ws?.enableCompression = compress
|
||||
ws?.delegate = self
|
||||
ws?.disableSSLCertValidation = selfSigned
|
||||
ws?.security = security
|
||||
|
||||
ws?.connect()
|
||||
}
|
||||
|
||||
/// Called when an error happens during execution. Causes a disconnection.
|
||||
public func didError(reason: String) {
|
||||
DefaultSocketLogger.Logger.error("%@", type: SocketEngine.logType, args: reason)
|
||||
@ -486,6 +472,44 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
}
|
||||
}
|
||||
|
||||
/// Called when a successful WebSocket connection is made.
|
||||
public func handleWSConnect() {
|
||||
if !forceWebsockets {
|
||||
probing = true
|
||||
probeWebSocket()
|
||||
} else {
|
||||
connected = true
|
||||
probing = false
|
||||
polling = false
|
||||
}
|
||||
}
|
||||
|
||||
/// Called when the WebSocket disconnects.
|
||||
public func handleWSDisconnect(error: NSError?) {
|
||||
probing = false
|
||||
|
||||
if closed {
|
||||
client?.engineDidClose(reason: "Disconnect")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
guard websocket else {
|
||||
flushProbeWait()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
connected = false
|
||||
websocket = false
|
||||
|
||||
if let reason = error?.localizedDescription {
|
||||
didError(reason: reason)
|
||||
} else {
|
||||
client?.engineDidClose(reason: "Socket Disconnected")
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses raw binary received from engine.io.
|
||||
///
|
||||
/// - parameter data: The data to parse.
|
||||
@ -601,45 +625,19 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
|
||||
}
|
||||
}
|
||||
|
||||
#if !os(Linux)
|
||||
// MARK: Starscream delegate conformance
|
||||
|
||||
/// Delegate method for connection.
|
||||
public func websocketDidConnect(socket: WebSocket) {
|
||||
if !forceWebsockets {
|
||||
probing = true
|
||||
probeWebSocket()
|
||||
} else {
|
||||
connected = true
|
||||
probing = false
|
||||
polling = false
|
||||
}
|
||||
handleWSConnect()
|
||||
}
|
||||
|
||||
/// Delegate method for disconnection.
|
||||
public func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
|
||||
probing = false
|
||||
|
||||
if closed {
|
||||
client?.engineDidClose(reason: "Disconnect")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
guard websocket else {
|
||||
flushProbeWait()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
connected = false
|
||||
websocket = false
|
||||
|
||||
if let reason = error?.localizedDescription {
|
||||
didError(reason: reason)
|
||||
} else {
|
||||
client?.engineDidClose(reason: "Socket Disconnected")
|
||||
}
|
||||
handleWSDisconnect(error: error)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
extension SocketEngine {
|
||||
|
||||
@ -24,7 +24,11 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if !os(Linux)
|
||||
import StarscreamSocketIO
|
||||
#else
|
||||
import WebSockets
|
||||
#endif
|
||||
|
||||
/// Specifies a SocketEngine.
|
||||
@objc public protocol SocketEngineSpec {
|
||||
@ -40,6 +44,9 @@ import StarscreamSocketIO
|
||||
/// The connect parameters sent during a connect.
|
||||
var connectParams: [String: Any]? { get set }
|
||||
|
||||
/// Whether or not to use WebSocket compression.
|
||||
var compress: Bool { get }
|
||||
|
||||
/// An array of HTTPCookies that are sent during the connection.
|
||||
var cookies: [HTTPCookie]? { get }
|
||||
|
||||
@ -64,6 +71,14 @@ import StarscreamSocketIO
|
||||
/// If `true`, the engine is currently seeing whether it can upgrade to WebSockets.
|
||||
var probing: Bool { get }
|
||||
|
||||
/// Whether or not this engine uses secure transports
|
||||
var secure: Bool { get }
|
||||
|
||||
var security: SSLSecurity? { get }
|
||||
|
||||
/// Whether or not to allow self signed certificates.
|
||||
var selfSigned: Bool { get }
|
||||
|
||||
/// The session id for this engine.
|
||||
var sid: String { get }
|
||||
|
||||
@ -80,7 +95,7 @@ import StarscreamSocketIO
|
||||
var websocket: Bool { get }
|
||||
|
||||
/// The WebSocket for this engine.
|
||||
var ws: WebSocket? { get }
|
||||
var ws: WebSocket? { get set }
|
||||
|
||||
/// Creates a new engine.
|
||||
///
|
||||
|
||||
@ -24,10 +24,22 @@
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if !os(Linux)
|
||||
import StarscreamSocketIO
|
||||
#else
|
||||
import WebSockets
|
||||
import Sockets
|
||||
import TLS
|
||||
#endif
|
||||
|
||||
/// Protocol that is used to implement socket.io WebSocket support
|
||||
public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {
|
||||
/// Called when a successful WebSocket connection is made.
|
||||
func handleWSConnect()
|
||||
|
||||
/// Called when the WebSocket disconnects.
|
||||
func handleWSDisconnect(error: NSError?)
|
||||
|
||||
/// Sends an engine.io message through the WebSocket transport.
|
||||
///
|
||||
/// You shouldn't call this directly, instead call the `write` method on `SocketEngine`.
|
||||
@ -40,6 +52,74 @@ public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {
|
||||
|
||||
// WebSocket methods
|
||||
extension SocketEngineWebsocket {
|
||||
#if os(Linux)
|
||||
func attachWebSocketHandlers() {
|
||||
ws?.onText = {[weak self] ws, text in
|
||||
guard let this = self else { return }
|
||||
|
||||
this.parseEngineMessage(text)
|
||||
}
|
||||
|
||||
ws?.onBinary = {[weak self] ws, bin in
|
||||
guard let this = self else { return }
|
||||
|
||||
this.parseEngineData(Data(bytes: bin))
|
||||
}
|
||||
|
||||
ws?.onClose = {[weak self] _, _, reason, clean in
|
||||
guard let this = self else { return }
|
||||
|
||||
this.handleWSDisconnect(error: nil)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
func createWebSocketAndConnect() {
|
||||
#if !os(Linux)
|
||||
ws?.delegate = nil // TODO this seems a bit defensive, is this really needed?
|
||||
ws = WebSocket(url: urlWebSocketWithSid)
|
||||
|
||||
if cookies != nil {
|
||||
let headers = HTTPCookie.requestHeaderFields(with: cookies!)
|
||||
for (key, value) in headers {
|
||||
ws?.headers[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
if extraHeaders != nil {
|
||||
for (headerName, value) in extraHeaders! {
|
||||
ws?.headers[headerName] = value
|
||||
}
|
||||
}
|
||||
|
||||
ws?.callbackQueue = engineQueue
|
||||
ws?.enableCompression = compress
|
||||
ws?.delegate = self
|
||||
ws?.disableSSLCertValidation = selfSigned
|
||||
ws?.security = security
|
||||
|
||||
ws?.connect()
|
||||
#else
|
||||
let url = urlWebSocketWithSid
|
||||
do {
|
||||
let socket = try TCPInternetSocket(scheme: url.scheme ?? "http",
|
||||
hostname: url.host ?? "localhost",
|
||||
port: Port(url.port ?? 80))
|
||||
let stream = secure ? try TLS.InternetSocket(socket, TLS.Context(.client)) : socket
|
||||
try WebSocket.background(to: connectURL, using: stream) {[weak self] ws in
|
||||
guard let this = self else { return }
|
||||
|
||||
this.ws = ws
|
||||
|
||||
this.attachWebSocketHandlers()
|
||||
this.handleWSConnect()
|
||||
}
|
||||
} catch {
|
||||
DefaultSocketLogger.Logger.error("Error connecting socket", type: "SocketEngineWebsocket")
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
func probeWebSocket() {
|
||||
if ws?.isConnected ?? false {
|
||||
sendWebSocketMessage("probe", withType: .ping, withData: [])
|
||||
@ -67,6 +147,7 @@ extension SocketEngineWebsocket {
|
||||
|
||||
// MARK: Starscream delegate methods
|
||||
|
||||
#if !os(Linux)
|
||||
/// Delegate method for when a message is received.
|
||||
public func websocketDidReceiveMessage(socket: WebSocket, text: String) {
|
||||
parseEngineMessage(text)
|
||||
@ -76,4 +157,16 @@ extension SocketEngineWebsocket {
|
||||
public func websocketDidReceiveData(socket: WebSocket, data: Data) {
|
||||
parseEngineData(data)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
/// SSLSecurity does nothing on Linux.
|
||||
public final class SSLSecurity { }
|
||||
|
||||
extension WebSocket {
|
||||
var isConnected: Bool {
|
||||
return state == .open
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user