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