Compare commits
	
		
			14 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					1faa4b925c | ||
| 
						 | 
					c20c286864 | ||
| 
						 | 
					239b30f2c8 | ||
| 
						 | 
					ecf9336132 | ||
| 
						 | 
					bcaf7ba62d | ||
| 
						 | 
					53289dc092 | ||
| 
						 | 
					d0420bc3c6 | ||
| 
						 | 
					26af5a6296 | ||
| 
						 | 
					4eccf87ecc | ||
| 
						 | 
					b85e42bbf9 | ||
| 
						 | 
					7120d89a17 | ||
| 
						 | 
					e0d8f16666 | ||
| 
						 | 
					95b3bfc802 | ||
| 
						 | 
					afc5a561d0 | 
@ -1,9 +1,15 @@
 | 
				
			|||||||
import PackageDescription
 | 
					import PackageDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let deps: [Package.Dependency]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
 | 
					deps = [.Package(url: "https://github.com/nuclearace/Starscream", majorVersion: 8)]
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					deps = [.Package(url: "https://github.com/vapor/engine", majorVersion: 2)]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
let package = Package(
 | 
					let package = Package(
 | 
				
			||||||
    name: "SocketIO",
 | 
					    name: "SocketIO",
 | 
				
			||||||
    dependencies: [
 | 
					    dependencies: deps,
 | 
				
			||||||
        .Package(url: "https://github.com/nuclearace/Starscream", majorVersion: 8),
 | 
					 | 
				
			||||||
    ],
 | 
					 | 
				
			||||||
    exclude: ["Source/Starscream"]
 | 
					    exclude: ["Source/Starscream"]
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
				
			|||||||
@ -136,6 +136,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
				
			|||||||
        super.init()
 | 
					        super.init()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if !os(Linux)
 | 
				
			||||||
    /// Not so type safe way to create a SocketIOClient, meant for Objective-C compatiblity.
 | 
					    /// Not so type safe way to create a SocketIOClient, meant for Objective-C compatiblity.
 | 
				
			||||||
    /// If using Swift it's recommended to use `init(socketURL: NSURL, options: Set<SocketIOClientOption>)`
 | 
					    /// If using Swift it's recommended to use `init(socketURL: NSURL, options: Set<SocketIOClientOption>)`
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
@ -144,6 +145,7 @@ open class SocketIOClient : NSObject, SocketIOClientSpec, SocketEngineClient, So
 | 
				
			|||||||
    public convenience init(socketURL: NSURL, config: NSDictionary?) {
 | 
					    public convenience init(socketURL: NSURL, config: NSDictionary?) {
 | 
				
			||||||
        self.init(socketURL: socketURL as URL, config: config?.toSocketConfiguration() ?? [])
 | 
					        self.init(socketURL: socketURL as URL, config: config?.toSocketConfiguration() ?? [])
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    deinit {
 | 
					    deinit {
 | 
				
			||||||
        DefaultSocketLogger.Logger.log("Client is being released", type: SocketIOClient.logType)
 | 
					        DefaultSocketLogger.Logger.log("Client is being released", type: SocketIOClient.logType)
 | 
				
			||||||
 | 
				
			|||||||
@ -22,8 +22,11 @@
 | 
				
			|||||||
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
//  THE SOFTWARE.
 | 
					//  THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Dispatch
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
import StarscreamSocketIO
 | 
					import StarscreamSocketIO
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protocol ClientOption : CustomStringConvertible, Equatable {
 | 
					protocol ClientOption : CustomStringConvertible, Equatable {
 | 
				
			||||||
    func getSocketIOOptionValue() -> Any
 | 
					    func getSocketIOOptionValue() -> Any
 | 
				
			||||||
 | 
				
			|||||||
@ -24,7 +24,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import Dispatch
 | 
					import Dispatch
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
import StarscreamSocketIO
 | 
					import StarscreamSocketIO
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					import WebSockets
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The class that handles the engine.io protocol and transports.
 | 
					/// The class that handles the engine.io protocol and transports.
 | 
				
			||||||
/// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods.
 | 
					/// See `SocketEnginePollable` and `SocketEngineWebsocket` for transport specific methods.
 | 
				
			||||||
@ -60,6 +64,9 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
    /// **Do not touch this directly**
 | 
					    /// **Do not touch this directly**
 | 
				
			||||||
    public var waitingForPost = false
 | 
					    public var waitingForPost = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The WebSocket for this engine.
 | 
				
			||||||
 | 
					    public var ws: WebSocket?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// `true` if this engine is closed.
 | 
					    /// `true` if this engine is closed.
 | 
				
			||||||
    public private(set) var closed = false
 | 
					    public private(set) var closed = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -95,6 +102,15 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
    /// If `true`, the engine is currently seeing whether it can upgrade to WebSockets.
 | 
					    /// If `true`, the engine is currently seeing whether it can upgrade to WebSockets.
 | 
				
			||||||
    public private(set) var probing = false
 | 
					    public private(set) var probing = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Whether or not this engine uses secure transports
 | 
				
			||||||
 | 
					    public private(set) var secure = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// A custom security validator for Starscream. Useful for SSL pinning.
 | 
				
			||||||
 | 
					    public private(set) var security: SSLSecurity?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Whether or not to allow self signed certificates.
 | 
				
			||||||
 | 
					    public private(set) var selfSigned = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The URLSession that will be used for polling.
 | 
					    /// The URLSession that will be used for polling.
 | 
				
			||||||
    public private(set) var session: URLSession?
 | 
					    public private(set) var session: URLSession?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -113,9 +129,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
    /// If `true`, then the engine is currently in WebSockets mode.
 | 
					    /// If `true`, then the engine is currently in WebSockets mode.
 | 
				
			||||||
    public private(set) var websocket = false
 | 
					    public private(set) var websocket = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The WebSocket for this engine.
 | 
					 | 
				
			||||||
    public private(set) var ws: WebSocket?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// The client for this engine.
 | 
					    /// The client for this engine.
 | 
				
			||||||
    public weak var client: SocketEngineClient?
 | 
					    public weak var client: SocketEngineClient?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -133,9 +146,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
    private var pongsMissed = 0
 | 
					    private var pongsMissed = 0
 | 
				
			||||||
    private var pongsMissedMax = 0
 | 
					    private var pongsMissedMax = 0
 | 
				
			||||||
    private var probeWait = ProbeWaitQueue()
 | 
					    private var probeWait = ProbeWaitQueue()
 | 
				
			||||||
    private var secure = false
 | 
					 | 
				
			||||||
    private var security: SSLSecurity?
 | 
					 | 
				
			||||||
    private var selfSigned = false
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // MARK: Initializers
 | 
					    // MARK: Initializers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -206,7 +216,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private func checkAndHandleEngineError(_ msg: String) {
 | 
					    private func checkAndHandleEngineError(_ msg: String) {
 | 
				
			||||||
        do {
 | 
					        do {
 | 
				
			||||||
            let dict = try msg.toNSDictionary()
 | 
					            let dict = try msg.toDictionary()
 | 
				
			||||||
            guard let error = dict["message"] as? String else { return }
 | 
					            guard let error = dict["message"] as? String else { return }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            /*
 | 
					            /*
 | 
				
			||||||
@ -308,32 +318,6 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
        return (urlPolling.url!, urlWebSocket.url!)
 | 
					        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.
 | 
					    /// Called when an error happens during execution. Causes a disconnection.
 | 
				
			||||||
    public func didError(reason: String) {
 | 
					    public func didError(reason: String) {
 | 
				
			||||||
        DefaultSocketLogger.Logger.error("%@", type: SocketEngine.logType, args: reason)
 | 
					        DefaultSocketLogger.Logger.error("%@", type: SocketEngine.logType, args: reason)
 | 
				
			||||||
@ -435,7 +419,7 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private func handleOpen(openData: String) {
 | 
					    private func handleOpen(openData: String) {
 | 
				
			||||||
        guard let json = try? openData.toNSDictionary() else {
 | 
					        guard let json = try? openData.toDictionary() else {
 | 
				
			||||||
            didError(reason: "Error parsing open packet")
 | 
					            didError(reason: "Error parsing open packet")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
@ -486,6 +470,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.
 | 
					    /// Parses raw binary received from engine.io.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// - parameter data: The data to parse.
 | 
					    /// - parameter data: The data to parse.
 | 
				
			||||||
@ -601,45 +623,19 @@ public final class SocketEngine : NSObject, URLSessionDelegate, SocketEnginePoll
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if !os(Linux)
 | 
				
			||||||
    // MARK: Starscream delegate conformance
 | 
					    // MARK: Starscream delegate conformance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Delegate method for connection.
 | 
					    /// Delegate method for connection.
 | 
				
			||||||
    public func websocketDidConnect(socket: WebSocket) {
 | 
					    public func websocketDidConnect(socket: WebSocket) {
 | 
				
			||||||
        if !forceWebsockets {
 | 
					        handleWSConnect()
 | 
				
			||||||
            probing = true
 | 
					 | 
				
			||||||
            probeWebSocket()
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            connected = true
 | 
					 | 
				
			||||||
            probing = false
 | 
					 | 
				
			||||||
            polling = false
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Delegate method for disconnection.
 | 
					    /// Delegate method for disconnection.
 | 
				
			||||||
    public func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
 | 
					    public func websocketDidDisconnect(socket: WebSocket, error: NSError?) {
 | 
				
			||||||
        probing = false
 | 
					        handleWSDisconnect(error: error)
 | 
				
			||||||
 | 
					 | 
				
			||||||
        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")
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extension SocketEngine {
 | 
					extension SocketEngine {
 | 
				
			||||||
 | 
				
			|||||||
@ -25,6 +25,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
/// Declares that a type will be a delegate to an engine.
 | 
					/// Declares that a type will be a delegate to an engine.
 | 
				
			||||||
@objc public protocol SocketEngineClient {
 | 
					@objc public protocol SocketEngineClient {
 | 
				
			||||||
    // MARK: Methods
 | 
					    // MARK: Methods
 | 
				
			||||||
@ -54,3 +55,34 @@ import Foundation
 | 
				
			|||||||
    /// - parameter data: The data the engine received.
 | 
					    /// - parameter data: The data the engine received.
 | 
				
			||||||
    func parseEngineBinaryData(_ data: Data)
 | 
					    func parseEngineBinaryData(_ data: Data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					/// Declares that a type will be a delegate to an engine.
 | 
				
			||||||
 | 
					public protocol SocketEngineClient : class {
 | 
				
			||||||
 | 
					    // MARK: Methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called when the engine errors.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter reason: The reason the engine errored.
 | 
				
			||||||
 | 
					    func engineDidError(reason: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called when the engine closes.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter reason: The reason that the engine closed.
 | 
				
			||||||
 | 
					    func engineDidClose(reason: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called when the engine opens.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter reason: The reason the engine opened.
 | 
				
			||||||
 | 
					    func engineDidOpen(reason: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called when the engine has a message that must be parsed.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter msg: The message that needs parsing.
 | 
				
			||||||
 | 
					    func parseEngineMessage(_ msg: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called when the engine receives binary data.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter data: The data the engine received.
 | 
				
			||||||
 | 
					    func parseEngineBinaryData(_ data: Data)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -23,9 +23,15 @@
 | 
				
			|||||||
//  THE SOFTWARE.
 | 
					//  THE SOFTWARE.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Dispatch
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
import StarscreamSocketIO
 | 
					import StarscreamSocketIO
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					import WebSockets
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
/// Specifies a SocketEngine.
 | 
					/// Specifies a SocketEngine.
 | 
				
			||||||
@objc public protocol SocketEngineSpec {
 | 
					@objc public protocol SocketEngineSpec {
 | 
				
			||||||
    /// The client for this engine.
 | 
					    /// The client for this engine.
 | 
				
			||||||
@ -40,6 +46,9 @@ import StarscreamSocketIO
 | 
				
			|||||||
    /// The connect parameters sent during a connect.
 | 
					    /// The connect parameters sent during a connect.
 | 
				
			||||||
    var connectParams: [String: Any]? { get set }
 | 
					    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.
 | 
					    /// An array of HTTPCookies that are sent during the connection.
 | 
				
			||||||
    var cookies: [HTTPCookie]? { get }
 | 
					    var cookies: [HTTPCookie]? { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -64,6 +73,15 @@ import StarscreamSocketIO
 | 
				
			|||||||
    /// If `true`, the engine is currently seeing whether it can upgrade to WebSockets.
 | 
					    /// If `true`, the engine is currently seeing whether it can upgrade to WebSockets.
 | 
				
			||||||
    var probing: Bool { get }
 | 
					    var probing: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Whether or not this engine uses secure transports
 | 
				
			||||||
 | 
					    var secure: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// A custom security validator for Starscream. Useful for SSL pinning.
 | 
				
			||||||
 | 
					    var security: SSLSecurity? { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Whether or not to allow self signed certificates.
 | 
				
			||||||
 | 
					    var selfSigned: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The session id for this engine.
 | 
					    /// The session id for this engine.
 | 
				
			||||||
    var sid: String { get }
 | 
					    var sid: String { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,7 +98,7 @@ import StarscreamSocketIO
 | 
				
			|||||||
    var websocket: Bool { get }
 | 
					    var websocket: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// The WebSocket for this engine.
 | 
					    /// The WebSocket for this engine.
 | 
				
			||||||
    var ws: WebSocket? { get }
 | 
					    var ws: WebSocket? { get set }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Creates a new engine.
 | 
					    /// Creates a new engine.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
@ -131,6 +149,123 @@ import StarscreamSocketIO
 | 
				
			|||||||
    /// - parameter withData: Any data that this message has.
 | 
					    /// - parameter withData: Any data that this message has.
 | 
				
			||||||
    func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data])
 | 
					    func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data])
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					public protocol SocketEngineSpec : class {
 | 
				
			||||||
 | 
					    /// The client for this engine.
 | 
				
			||||||
 | 
					    var client: SocketEngineClient? { get set }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// `true` if this engine is closed.
 | 
				
			||||||
 | 
					    var closed: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// `true` if this engine is connected. Connected means that the initial poll connect has succeeded.
 | 
				
			||||||
 | 
					    var connected: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// 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 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The queue that all engine actions take place on.
 | 
				
			||||||
 | 
					    var engineQueue: DispatchQueue { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// A dictionary of extra http headers that will be set during connection.
 | 
				
			||||||
 | 
					    var extraHeaders: [String: String]? { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// When `true`, the engine is in the process of switching to WebSockets.
 | 
				
			||||||
 | 
					    var fastUpgrade: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// When `true`, the engine will only use HTTP long-polling as a transport.
 | 
				
			||||||
 | 
					    var forcePolling: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// When `true`, the engine will only use WebSockets as a transport.
 | 
				
			||||||
 | 
					    var forceWebsockets: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// If `true`, the engine is currently in HTTP long-polling mode.
 | 
				
			||||||
 | 
					    var polling: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// 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 }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The path to engine.io.
 | 
				
			||||||
 | 
					    var socketPath: String { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The url for polling.
 | 
				
			||||||
 | 
					    var urlPolling: URL { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The url for WebSockets.
 | 
				
			||||||
 | 
					    var urlWebSocket: URL { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// If `true`, then the engine is currently in WebSockets mode.
 | 
				
			||||||
 | 
					    var websocket: Bool { get }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The WebSocket for this engine.
 | 
				
			||||||
 | 
					    var ws: WebSocket? { get set }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Creates a new engine.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter client: The client for this engine.
 | 
				
			||||||
 | 
					    /// - parameter url: The url for this engine.
 | 
				
			||||||
 | 
					    /// - parameter options: The options for this engine.
 | 
				
			||||||
 | 
					    init(client: SocketEngineClient, url: URL, options: NSDictionary?)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Starts the connection to the server.
 | 
				
			||||||
 | 
					    func connect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called when an error happens during execution. Causes a disconnection.
 | 
				
			||||||
 | 
					    func didError(reason: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Disconnects from the server.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter reason: The reason for the disconnection. This is communicated up to the client.
 | 
				
			||||||
 | 
					    func disconnect(reason: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Called to switch from HTTP long-polling to WebSockets. After calling this method the engine will be in
 | 
				
			||||||
 | 
					    /// WebSocket mode.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// **You shouldn't call this directly**
 | 
				
			||||||
 | 
					    func doFastUpgrade()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Causes any packets that were waiting for POSTing to be sent through the WebSocket. This happens because when
 | 
				
			||||||
 | 
					    /// the engine is attempting to upgrade to WebSocket it does not do any POSTing.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// **You shouldn't call this directly**
 | 
				
			||||||
 | 
					    func flushWaitingForPostToWebSocket()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Parses raw binary received from engine.io.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter data: The data to parse.
 | 
				
			||||||
 | 
					    func parseEngineData(_ data: Data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Parses a raw engine.io packet.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter message: The message to parse.
 | 
				
			||||||
 | 
					    /// - parameter fromPolling: Whether this message is from long-polling.
 | 
				
			||||||
 | 
					    ///                          If `true` we might have to fix utf8 encoding.
 | 
				
			||||||
 | 
					    func parseEngineMessage(_ message: String)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Writes a message to engine.io, independent of transport.
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// - parameter msg: The message to send.
 | 
				
			||||||
 | 
					    /// - parameter withType: The type of this message.
 | 
				
			||||||
 | 
					    /// - parameter withData: Any data that this message has.
 | 
				
			||||||
 | 
					    func write(_ msg: String, withType type: SocketEnginePacketType, withData data: [Data])
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extension SocketEngineSpec {
 | 
					extension SocketEngineSpec {
 | 
				
			||||||
    var urlPollingWithSid: URL {
 | 
					    var urlPollingWithSid: URL {
 | 
				
			||||||
@ -161,12 +296,11 @@ extension SocketEngineSpec {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    func createBinaryDataForSend(using data: Data) -> Either<Data, String> {
 | 
					    func createBinaryDataForSend(using data: Data) -> Either<Data, String> {
 | 
				
			||||||
        if websocket {
 | 
					        if websocket {
 | 
				
			||||||
            var byteArray = [UInt8](repeating: 0x4, count: 1)
 | 
					            var mutData = Data(bytes: [UInt8](repeating: 0x4, count: 1))
 | 
				
			||||||
            let mutData = NSMutableData(bytes: &byteArray, length: 1)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            mutData.append(data)
 | 
					            mutData.append(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return .left(mutData as Data)
 | 
					            return .left(mutData)
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return .right("b4" + data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)))
 | 
					            return .right("b4" + data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)))
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
				
			|||||||
@ -24,10 +24,22 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
import StarscreamSocketIO
 | 
					import StarscreamSocketIO
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					import WebSockets
 | 
				
			||||||
 | 
					import Sockets
 | 
				
			||||||
 | 
					import TLS
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Protocol that is used to implement socket.io WebSocket support
 | 
					/// Protocol that is used to implement socket.io WebSocket support
 | 
				
			||||||
public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {
 | 
					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.
 | 
					    /// Sends an engine.io message through the WebSocket transport.
 | 
				
			||||||
    ///
 | 
					    ///
 | 
				
			||||||
    /// You shouldn't call this directly, instead call the `write` method on `SocketEngine`.
 | 
					    /// You shouldn't call this directly, instead call the `write` method on `SocketEngine`.
 | 
				
			||||||
@ -40,6 +52,89 @@ public protocol SocketEngineWebsocket : SocketEngineSpec, WebSocketDelegate {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// WebSocket methods
 | 
					// WebSocket methods
 | 
				
			||||||
extension SocketEngineWebsocket {
 | 
					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))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if secure {
 | 
				
			||||||
 | 
					                let stream = try TLS.InternetSocket(socket, TLS.Context(.client))
 | 
				
			||||||
 | 
					                try WebSocket.background(to: urlWebSocketWithSid.absoluteString, using: stream) {[weak self] ws in
 | 
				
			||||||
 | 
					                    guard let this = self else { return }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.onConnect(ws: ws)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                try WebSocket.background(to: urlWebSocketWithSid.absoluteString, using: socket) {[weak self] ws in
 | 
				
			||||||
 | 
					                    guard let this = self else { return }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    this.onConnect(ws: ws)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch {
 | 
				
			||||||
 | 
					            DefaultSocketLogger.Logger.error("Error connecting socket", type: "SocketEngineWebsocket")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if os(Linux)
 | 
				
			||||||
 | 
					    func onConnect(ws: WebSocket) {
 | 
				
			||||||
 | 
					        self.ws = ws
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attachWebSocketHandlers()
 | 
				
			||||||
 | 
					        handleWSConnect()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    func probeWebSocket() {
 | 
					    func probeWebSocket() {
 | 
				
			||||||
        if ws?.isConnected ?? false {
 | 
					        if ws?.isConnected ?? false {
 | 
				
			||||||
            sendWebSocketMessage("probe", withType: .ping, withData: [])
 | 
					            sendWebSocketMessage("probe", withType: .ping, withData: [])
 | 
				
			||||||
@ -65,6 +160,7 @@ extension SocketEngineWebsocket {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if !os(Linux)
 | 
				
			||||||
    // MARK: Starscream delegate methods
 | 
					    // MARK: Starscream delegate methods
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// Delegate method for when a message is received.
 | 
					    /// Delegate method for when a message is received.
 | 
				
			||||||
@ -76,4 +172,45 @@ extension SocketEngineWebsocket {
 | 
				
			|||||||
    public func websocketDidReceiveData(socket: WebSocket, data: Data) {
 | 
					    public func websocketDidReceiveData(socket: WebSocket, data: Data) {
 | 
				
			||||||
        parseEngineData(data)
 | 
					        parseEngineData(data)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if os(Linux)
 | 
				
			||||||
 | 
					/// Does nothing on Linux.
 | 
				
			||||||
 | 
					public protocol WebSocketDelegate { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// SSLSecurity does nothing on Linux.
 | 
				
			||||||
 | 
					public final class SSLSecurity { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extension WebSocket {
 | 
				
			||||||
 | 
					    var isConnected: Bool {
 | 
				
			||||||
 | 
					        return state == .open
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    func disconnect() {
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            try close()
 | 
				
			||||||
 | 
					        } catch {
 | 
				
			||||||
 | 
					            DefaultSocketLogger.Logger.error("Error closing ws", type: "SocketEngineWebsocket")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    func write(string: String) {
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            try send(string)
 | 
				
			||||||
 | 
					        } catch {
 | 
				
			||||||
 | 
					            DefaultSocketLogger.Logger.error("Error sending string", type: "SocketEngineWebsocket", args: string)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    func write(data: Data) {
 | 
				
			||||||
 | 
					        do {
 | 
				
			||||||
 | 
					            try data.withUnsafeBytes {(bytes: UnsafePointer<UInt8>) in
 | 
				
			||||||
 | 
					                try self.send(Array(UnsafeBufferPointer(start: bytes, count: data.count)))
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch {
 | 
				
			||||||
 | 
					            DefaultSocketLogger.Logger.error("Error sending data", type: "SocketEngineWebsocket", args: data)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -22,8 +22,11 @@
 | 
				
			|||||||
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
//  THE SOFTWARE.
 | 
					//  THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Dispatch
 | 
				
			||||||
import Foundation
 | 
					import Foundation
 | 
				
			||||||
 | 
					#if !os(Linux)
 | 
				
			||||||
import StarscreamSocketIO
 | 
					import StarscreamSocketIO
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum JSONError : Error {
 | 
					enum JSONError : Error {
 | 
				
			||||||
    case notArray
 | 
					    case notArray
 | 
				
			||||||
@ -111,9 +114,9 @@ extension String {
 | 
				
			|||||||
        return array
 | 
					        return array
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    func toNSDictionary() throws -> NSDictionary {
 | 
					    func toDictionary() throws -> [String: Any] {
 | 
				
			||||||
        guard let binData = data(using: .utf16, allowLossyConversion: false) else { return [:] }
 | 
					        guard let binData = data(using: .utf16, allowLossyConversion: false) else { return [:] }
 | 
				
			||||||
        guard let json = try JSONSerialization.jsonObject(with: binData, options: .allowFragments) as? NSDictionary else {
 | 
					        guard let json = try JSONSerialization.jsonObject(with: binData, options: .allowFragments) as? [String: Any] else {
 | 
				
			||||||
            throw JSONError.notNSDictionary
 | 
					            throw JSONError.notNSDictionary
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -62,10 +62,12 @@ public extension SocketLogger {
 | 
				
			|||||||
    private func abstractLog(_ logType: String, message: String, type: String, args: [Any]) {
 | 
					    private func abstractLog(_ logType: String, message: String, type: String, args: [Any]) {
 | 
				
			||||||
        guard log else { return }
 | 
					        guard log else { return }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #if !os(Linux)
 | 
				
			||||||
        let newArgs = args.map({arg -> CVarArg in String(describing: arg)})
 | 
					        let newArgs = args.map({arg -> CVarArg in String(describing: arg)})
 | 
				
			||||||
        let messageFormat = String(format: message, arguments: newArgs)
 | 
					        let messageFormat = String(format: message, arguments: newArgs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        NSLog("\(logType) \(type): %@", messageFormat)
 | 
					        NSLog("\(logType) \(type): %@", messageFormat)
 | 
				
			||||||
 | 
					        #endif
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user