I have an app where I an supposed to have a websocket that listens only when the app is in the foreground I have tapped into the lifecycle notifications and call start() and stop accordingly. The app works correctly until the appication comes back to the foreground, at which point I get a number of warnings and errors.
class SwiftWebSocketServer {
let port: NWEndpoint.Port
var listener: NWListener?
var listenerState: NWListener.State
let eventHandler:()->Void
var connection: ServerConnection?
init(port: UInt16, handler:@escaping ()->Void) {
self.port = NWEndpoint.Port(rawValue: port)!
listenerState = .cancelled
self.eventHandler = handler
let parameters = NWParameters(tls: nil)
parameters.allowLocalEndpointReuse = true
parameters.includePeerToPeer = true
let wsOptions = NWProtocolWebSocket.Options()
wsOptions.autoReplyPing = true
parameters.defaultProtocolStack.applicationProtocols.insert(wsOptions, at: 0)
do {
listener = try NWListener(using: parameters, on: self.port)
listener!.stateUpdateHandler = self.stateDidChange(to:)
listener!.newConnectionHandler = self.didAccept(nwConnection:)
} catch {
print(#function, error)
}
}
func start() throws {
print("Server starting...")
listener!.stateUpdateHandler = self.stateDidChange(to:)
listener!.newConnectionHandler = self.didAccept(nwConnection:)
listener!.start(queue: .main)
print("Server started.")
eventHandler()
}
func stop() {
self.listener!.stateUpdateHandler = nil
self.listener!.newConnectionHandler = nil
self.listener!.cancel()
print("Server cancelled")
connection?.stop()
connection?.didStopCallback = nil
connection = nil
eventHandler()
}
func stateDidChange(to newState: NWListener.State) {
print(#function, newState)
switch newState {
case .ready:
print("Server ready.")
case .failed(let error):
print("Server failure, error: \(error.localizedDescription)")
exit(EXIT_FAILURE)
default:
break
}
listenerState = newState
eventHandler()
}
}
Log:
Server starting...
Server started
App moved to background!
Server cancelled
App moved to foreground!
Server starting...
2020-07-30 13:45:48.269100-0400 rfa-ios-native[584:10739501] [] nw_listener_set_queue Error in client: nw_listener_set_queue called after nw_listener_start
2020-07-30 13:45:48.271526-0400 rfa-ios-native[584:10739501] [] nw_listener_set_queue Error in client: nw_listener_set_queue called after nw_listener_start, dumping backtrace:
[arm64] libnetcore-1880.40.26
0 libnetwork.dylib 0x00000001c5cb9ae8 __nw_create_backtrace_string + 116
1 libnetwork.dylib 0x00000001c5bd8c3c nw_listener_set_queue + 224
2 libswiftNetwork.dylib 0x00000001f86c737c $s7Network10NWListenerC5start5queueySo012OS_dispatch_D0C_tF + 52
3 rfa-ios-native 0x0000000104f64ec4 $s14rfa_ios_native20SwiftWebSocketServerC5startyyKF + 432
4 rfa-ios-native 0x0000000104f34468 $s14rfa_ios_native14ViewControllerC20appMovedToForegroundyyF + 296
5 rfa-ios-native 0x0000000104f34634 $s14rfa_ios_native14ViewControllerC20appMovedToForegroundyyFTo + 48
...
Server started.
Even beyond the messages and the stacktrace, the listener is not listening. What do I have to do to be able to cancel listen and re-listen on the same port?
