add ability to specify custom logger

This commit is contained in:
Erik 2015-09-03 15:10:18 -04:00
parent 0ff4cb9713
commit 8d0af14f04
6 changed files with 80 additions and 60 deletions

View File

@ -121,6 +121,7 @@ Options
- `nsp: String` Default is `"/"`. Connects to a namespace.
- `cookies: [NSHTTPCookie]?` An array of NSHTTPCookies. Passed during the handshake. Default is nil.
- `log: Bool` If `true` socket will log debug messages. Default is false.
- `logger: SocketLogger` If you wish to implement your own logger that conforms to SocketLogger you can pass it in here. Will use the default logging defined under the protocol otherwise.
- `sessionDelegate: NSURLSessionDelegate` Sets an NSURLSessionDelegate for the underlying engine. Useful if you need to handle self-signed certs. Default is nil.
- `path: String` - If the server uses a custom path. ex: `"/swift"`. Default is `""`
- `extraHeaders: [String: String]?` - Adds custom headers to the initial request. Default is nil.

View File

@ -25,6 +25,8 @@
import Foundation
public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
public let logType = "SocketEngine"
private typealias Probe = (msg: String, type: PacketType, data: [NSData]?)
private typealias ProbeWaitQueue = [Probe]
@ -56,8 +58,6 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
private var waitingForPost = false
private var websocketConnected = false
let logType = "SocketEngine"
private(set) var connected = false
private(set) var polling = true
private(set) var websocket = false
@ -69,7 +69,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
var urlPolling: String?
var urlWebSocket: String?
var ws: WebSocket?
public enum PacketType: Int {
case Open, Close, Ping, Pong, Message, Upgrade, Noop
@ -98,11 +98,11 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
}
deinit {
SocketLogger.log("Engine is being deinit", client: self)
Logger.log("Engine is being deinit", client: self, altType: nil)
}
public func close(fast fast: Bool) {
SocketLogger.log("Engine is being closed. Fast: %@", client: self, args: fast)
Logger.log("Engine is being closed. Fast: %@", client: self, altType: nil, args: fast)
pingTimer?.invalidate()
closed = true
@ -199,8 +199,8 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
private func doFastUpgrade() {
if waitingForPoll {
SocketLogger.err("Outstanding poll when switched to WebSockets," +
"we'll probably disconnect soon. You should report this.", client: self)
Logger.err("Outstanding poll when switched to WebSockets," +
"we'll probably disconnect soon. You should report this.", client: self, altType: nil)
}
sendWebSocketMessage("", withType: PacketType.Upgrade, datas: nil)
@ -240,7 +240,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
req.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
SocketLogger.log("Doing polling request", client: self)
Logger.log("Doing polling request", client: self, altType: nil)
session.dataTaskWithRequest(req) {[weak self] data, res, err in
if let this = self {
@ -248,12 +248,12 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
if this.polling {
this.handlePollingFailed(err?.localizedDescription ?? "Error")
} else {
SocketLogger.err(err?.localizedDescription ?? "Error", client: this)
Logger.err(err?.localizedDescription ?? "Error", client: this, altType: nil)
}
return
}
SocketLogger.log("Got polling response", client: this)
Logger.log("Got polling response", client: this, altType: nil)
if let str = NSString(data: data!, encoding: NSUTF8StringEncoding) as? String {
dispatch_async(this.parseQueue) {[weak this] in
@ -272,7 +272,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
}
private func flushProbeWait() {
SocketLogger.log("Flushing probe wait", client: self)
Logger.log("Flushing probe wait", client: self, altType: nil)
dispatch_async(emitQueue) {[weak self] in
if let this = self {
@ -325,7 +325,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
waitingForPost = true
SocketLogger.log("POSTing: %@", client: self, args: postStr)
Logger.log("POSTing: %@", client: self, altType: nil, args: postStr)
session.dataTaskWithRequest(req) {[weak self] data, res, err in
if let this = self {
@ -412,7 +412,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
}
}
} catch {
SocketLogger.err("Error parsing open packet", client: self)
Logger.err("Error parsing open packet", client: self, altType: nil)
return
}
@ -448,14 +448,14 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
public func open(opts: [String: AnyObject]? = nil) {
if connected {
SocketLogger.err("Tried to open while connected", client: self)
Logger.err("Tried to open while connected", client: self, altType: nil)
client?.didError("Tried to open while connected")
return
}
SocketLogger.log("Starting engine", client: self)
SocketLogger.log("Handshaking", client: self)
Logger.log("Starting engine", client: self, altType: nil)
Logger.log("Handshaking", client: self, altType: nil)
closed = false
@ -512,7 +512,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
length += chr
} else {
if length == "" || testLength(length, n: &n) {
SocketLogger.err("Parsing error: %@", client: self, args: str)
Logger.err("Parsing error: %@", client: self, altType: nil, args: str)
handlePollingFailed("Error parsing XHR message")
return
}
@ -520,7 +520,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
msg = String(strArray[i+1...i+n])
if let lengthInt = Int(length) where lengthInt != msg.characters.count {
SocketLogger.err("Parsing error: %@", client: self, args: str)
Logger.err("Parsing error: %@", client: self, altType: nil, args: str)
return
}
@ -542,7 +542,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
}
private func parseEngineMessage(var message: String, fromPolling: Bool) {
SocketLogger.log("Got message: %@", client: self, args: message)
Logger.log("Got message: %@", client: self, altType: nil, args: message)
if fromPolling {
fixDoubleUTF8(&message)
@ -567,7 +567,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
case PacketType.Close:
handleClose()
default:
SocketLogger.log("Got unknown packet type", client: self)
Logger.log("Got unknown packet type", client: self, altType: nil)
}
}
@ -602,7 +602,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
/// Only call on emitQueue
private func sendPollMessage(var msg: String, withType type: PacketType,
datas:[NSData]? = nil) {
SocketLogger.log("Sending poll: %@ as type: %@", client: self, args: msg, type.rawValue)
Logger.log("Sending poll: %@ as type: %@", client: self, altType: nil, args: msg, type.rawValue)
doubleEncodeUTF8(&msg)
let strMsg = "\(type.rawValue)\(msg)"
@ -626,7 +626,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
/// Only call on emitQueue
private func sendWebSocketMessage(str: String, withType type: PacketType,
datas:[NSData]? = nil) {
SocketLogger.log("Sending ws: %@ as type: %@", client: self, args: str, type.rawValue)
Logger.log("Sending ws: %@ as type: %@", client: self, altType: nil, args: str, type.rawValue)
ws?.writeString("\(type.rawValue)\(str)")
@ -661,7 +661,7 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
private func upgradeTransport() {
if websocketConnected {
SocketLogger.log("Upgrading transport to WebSockets", client: self)
Logger.log("Upgrading transport to WebSockets", client: self, altType: nil)
fastUpgrade = true
sendPollMessage("", withType: PacketType.Noop)
@ -676,11 +676,11 @@ public final class SocketEngine: NSObject, WebSocketDelegate, SocketLogClient {
dispatch_async(emitQueue) {[weak self] in
if let this = self where this.connected {
if this.websocket {
SocketLogger.log("Writing ws: %@ has data: %@", client: this,
Logger.log("Writing ws: %@ has data: %@", client: this, altType: nil,
args: msg, data == nil ? false : true)
this.sendWebSocketMessage(msg, withType: type, datas: data)
} else {
SocketLogger.log("Writing poll: %@ has data: %@", client: this,
Logger.log("Writing poll: %@ has data: %@", client: this, altType: nil,
args: msg, data == nil ? false : true)
this.sendPollMessage(msg, withType: type, datas: data)
}

View File

@ -32,13 +32,13 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
private var reconnectTimer: NSTimer?
let reconnectAttempts: Int!
let logType = "SocketClient"
var ackHandlers = SocketAckManager()
var currentAck = -1
var waitingData = [SocketPacket]()
public let emitQueue = dispatch_queue_create("emitQueue", DISPATCH_QUEUE_SERIAL)
public let handleQueue: dispatch_queue_t!
public let logType = "SocketClient"
public let socketURL: String
public private(set) var engine: SocketEngine?
@ -71,8 +71,12 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
self.connectParams = connectParams
}
if let logger = opts?["logger"] as? SocketLogger {
Logger = logger
}
if let log = opts?["log"] as? Bool {
SocketLogger.log = log
Logger.log = log
}
if let nsp = opts?["nsp"] as? String {
@ -103,12 +107,12 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
}
deinit {
SocketLogger.log("Client is being deinit", client: self)
Logger.log("Client is being deinit", client: self, altType: nil)
engine?.close(fast: true)
}
private func addEngine() {
SocketLogger.log("Adding engine", client: self)
Logger.log("Adding engine", client: self, altType: nil)
engine = SocketEngine(client: self, opts: opts)
}
@ -124,7 +128,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
Pass true to fast if you're closing from a background task
*/
public func close(fast fast: Bool) {
SocketLogger.log("Closing socket", client: self)
Logger.log("Closing socket", client: self, altType: nil)
reconnects = false
status = SocketIOClientStatus.Closed
@ -147,7 +151,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
return
}
if status == SocketIOClientStatus.Closed {
SocketLogger.log("Warning! This socket was previously closed. This might be dangerous!", client: self)
Logger.log("Warning! This socket was previously closed. This might be dangerous!",
client: self, altType: nil)
}
status = SocketIOClientStatus.Connecting
@ -191,7 +196,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
}
func didConnect() {
SocketLogger.log("Socket connected", client: self)
Logger.log("Socket connected", client: self, altType: nil)
status = SocketIOClientStatus.Connected
currentReconnectAttempt = 0
clearReconnectTimer()
@ -206,7 +211,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
return
}
SocketLogger.log("Disconnected: %@", client: self, args: reason)
Logger.log("Disconnected: %@", client: self, altType: nil, args: reason)
status = SocketIOClientStatus.Closed
@ -219,7 +224,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
/// error
public func didError(reason: AnyObject) {
SocketLogger.err("%@", client: self, args: reason)
Logger.err("%@", client: self, altType: nil, args: reason)
handleEvent("error", data: reason as? [AnyObject] ?? [reason],
isInternalMessage: true)
@ -275,7 +280,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
let packet = SocketPacket.packetFromEmit(data, id: ack ?? -1, nsp: nsp, ack: false)
let str = packet.packetString
SocketLogger.log("Emitting: %@", client: self, args: str)
Logger.log("Emitting: %@", client: self, altType: nil, args: str)
if packet.type == SocketPacket.PacketType.BinaryEvent {
engine?.send(str, withData: packet.binary)
@ -291,7 +296,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
let packet = SocketPacket.packetFromEmit(items, id: ack ?? -1, nsp: this.nsp, ack: true)
let str = packet.packetString
SocketLogger.log("Emitting Ack: %@", client: this, args: str)
Logger.log("Emitting Ack: %@", client: this, altType: nil, args: str)
if packet.type == SocketPacket.PacketType.BinaryAck {
this.engine?.send(str, withData: packet.binary)
@ -317,8 +322,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
// Called when the socket gets an ack for something it sent
func handleAck(ack: Int, data: AnyObject?) {
SocketLogger.log("Handling ack: %@ with data: %@", client: self,
args: ack, data ?? "")
Logger.log("Handling ack: %@ with data: %@", client: self,
altType: nil, args: ack, data ?? "")
ackHandlers.executeAck(ack,
items: (data as? [AnyObject]?) ?? (data != nil ? [data!] : nil))
@ -334,8 +339,8 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
}
// println("Should do event: \(event) with data: \(data)")
SocketLogger.log("Handling event: %@ with data: %@", client: self,
args: event, data ?? "")
Logger.log("Handling event: %@ with data: %@", client: self,
altType: nil, args: event, data ?? "")
if anyHandler != nil {
dispatch_async(handleQueue) {[weak self] in
@ -370,7 +375,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
Joins nsp if it is not /
*/
public func joinNamespace() {
SocketLogger.log("Joining namespace", client: self)
Logger.log("Joining namespace", client: self, altType: nil)
if nsp != "/" {
engine?.send("0\(nsp)", withData: nil)
@ -389,7 +394,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
Removes handler(s)
*/
public func off(event: String) {
SocketLogger.log("Removing handler for event: %@", client: self, args: event)
Logger.log("Removing handler for event: %@", client: self, altType: nil, args: event)
handlers = ContiguousArray(handlers.filter {!($0.event == event)})
}
@ -398,7 +403,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
Adds a handler for an event.
*/
public func on(event: String, callback: NormalCallback) {
SocketLogger.log("Adding handler for event: %@", client: self, args: event)
Logger.log("Adding handler for event: %@", client: self, altType: nil, args: event)
let handler = SocketEventHandler(event: event, callback: callback)
handlers.append(handler)
@ -408,7 +413,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
Adds a handler for an event.
*/
public func onObjectiveC(event: String, callback: NormalCallbackObjectiveC) {
SocketLogger.log("Adding handler for event: %@", client: self, args: event)
Logger.log("Adding handler for event: %@", client: self, altType: nil, args: event)
let handler = SocketEventHandler(event: event, callback: callback)
handlers.append(handler)
@ -462,7 +467,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
private func tryReconnect() {
if reconnectTimer == nil {
SocketLogger.log("Starting reconnect", client: self)
Logger.log("Starting reconnect", client: self, altType: nil)
status = SocketIOClientStatus.Reconnecting
@ -490,7 +495,7 @@ public final class SocketIOClient: NSObject, SocketEngineClient, SocketLogClient
return
}
SocketLogger.log("Trying to reconnect", client: self)
Logger.log("Trying to reconnect", client: self, altType: nil)
handleEvent("reconnectAttempt", data: [reconnectAttempts - currentReconnectAttempt],
isInternalMessage: true)

View File

@ -47,5 +47,4 @@ import Foundation
}
case NotConnected, Closed, Connecting, Connected, Reconnecting
}

View File

@ -24,41 +24,56 @@
import Foundation
protocol SocketLogClient {
var Logger: SocketLogger = DefaultSocketLogger(log: false)
public protocol SocketLogClient {
/// The type of object being logged
var logType: String {get}
}
final class SocketLogger {
private static let printQueue = dispatch_queue_create("printQueue", DISPATCH_QUEUE_SERIAL)
static var log = false
public protocol SocketLogger {
/// Whether to log or not
var log: Bool {get set}
private static func toCVArgType(item: AnyObject) -> CVarArgType {
return String(item)
/// Normal log messages
func log(message: String, client: SocketLogClient, altType: String?, args: AnyObject...)
/// Error Messages
func err(message: String, client: SocketLogClient, altType: String?, args: AnyObject...)
}
extension SocketLogger {
private var printQueue: dispatch_queue_t {
return dispatch_queue_create("printQueue", DISPATCH_QUEUE_SERIAL)
}
static func log(message: String, client: SocketLogClient, altType: String? = nil, args: AnyObject...) {
public func log(message: String, client: SocketLogClient, altType: String?, args: AnyObject...) {
if !log {
return
}
dispatch_async(printQueue) {[type = client.logType] in
let newArgs = args.map(SocketLogger.toCVArgType)
let newArgs = args.map {String($0)}
let replaced = String(format: message, arguments: newArgs)
NSLog("%@: %@", altType ?? type, replaced)
}
}
static func err(message: String, client: SocketLogClient, altType: String? = nil, args: AnyObject...) {
public func err(message: String, client: SocketLogClient, altType: String?, args: AnyObject...) {
if !log {
return
}
dispatch_async(printQueue) {[type = client.logType] in
let newArgs = args.map(SocketLogger.toCVArgType)
let newArgs = args.map {String($0)}
let replaced = String(format: message, arguments: newArgs)
NSLog("ERROR %@: %@", altType ?? type, replaced)
}
}
}
struct DefaultSocketLogger: SocketLogger {
var log: Bool
}

View File

@ -177,7 +177,7 @@ class SocketParser {
return
}
SocketLogger.log("Parsing %@", client: socket, altType: "SocketParser", args: stringMessage)
Logger.log("Parsing %@", client: socket, altType: "SocketParser", args: stringMessage)
let p: SocketPacket
@ -188,7 +188,7 @@ class SocketParser {
return
}
SocketLogger.log("Decoded packet as: %@", client: socket, altType: "SocketParser", args: p.description)
Logger.log("Decoded packet as: %@", client: socket, altType: "SocketParser", args: p.description)
switch p.type {
case SocketPacket.PacketType.Event:
@ -210,7 +210,7 @@ class SocketParser {
static func parseBinaryData(data: NSData, socket: SocketIOClient) {
if socket.waitingData.count == 0 {
SocketLogger.err("Got data when not remaking packet", client: socket, altType: "SocketParser")
Logger.err("Got data when not remaking packet", client: socket, altType: "SocketParser")
return
}