Post

Replies

Boosts

Views

Activity

NWListener, NWConnection, not accepting connections
I'm using NWListener with NWConnection. This code work great and I am able to start the listener and successfully receive connections in Xcode preview. However, when I build/run on my phone, the listener does not seem to accept connections from the network. If the app sends a message to itself on the phone, it is received, but if I send a message to that ip/port from another network device, it is not accepted/received. Any help or suggestions appreciated. import Foundation import Network import Combine @Observable class UDPListener3 { var listener: NWListener? var queue = DispatchQueue.global(qos: .userInitiated) var messageReceived: Data? private(set) var isReady: Bool private(set) var listening: Bool = false private(set) var receiving: Bool = false private(set) var port: UInt16 = 0 init () { isReady = false listening = false receiving = false messageReceived = nil listener = nil } func GetPort() { var portText = "\(String(describing: listener!.port))" portText = portText.replacingOccurrences(of: "Optional(", with: "") portText = portText.replacingOccurrences(of: ")", with: "") portText = portText.replacingOccurrences(of: ",", with: "") port = UInt16(portText)! if let testPort = listener?.port?.rawValue { self.port = testPort } } func config(port: Int) { if port > 0 { configinit(port: NWEndpoint.Port(integerLiteral: NWEndpoint.Port.IntegerLiteralType(port))) } else { configinit(port: nil) } } func configinit(port: NWEndpoint.Port?) { // conifigure and create listener let params = NWParameters.tcp params.allowFastOpen = true if port == nil { self.listener = try? NWListener(using: params, on: .any)//port) } else { self.listener = try? NWListener(using: params, on: port!) } if listener != nil { GetPort() self.listening = true self.listener?.stateUpdateHandler = { [self] update in switch update { case .ready: self.isReady = true print("*Listener.ready on port \(String(describing: self.listener?.port))") GetPort() case .failed: // Announce we are no longer able to listen self.listening = false self.isReady = false print("*Listener.failed on port \(port)") case .cancelled: // Announce we are no longer able to listen self.listening = false self.isReady = false print("*Listener.canceled on port \(port)") default: print("*Listener default connecting to port \(port)... \(self.listener!.state)") } print() } self.listener?.newConnectionHandler = { connection in print("@called listener.newConnectionHandler") self.createConnection(connection: connection) } // start listening self.listener?.start(queue: self.queue) GetPort() } else { print("unable to start listener") } } func createConnection(connection: NWConnection) { connection.stateUpdateHandler = { (newState) in switch (newState) { case .ready: print(" ...Connection.ready")// - \(connection)") self.receive(connection) case .cancelled: print(" ...Connection.cancelled")// - \(connection)") case .failed: print(" ...Connection.failed")// - \(connection)") default: print(" ...Connection.default: \(connection.state)")// - \(connection)") } } print(" ...connection starting") connection.start(queue: .global()) } func receive(_ connection: NWConnection) { print() print(" ...connection receiving") // respond 200 received self.respond(on: connection) //connection.receiveMessage() { [self] data, context, isComplete, error in //<-- this would not return until timeout expired?? connection.receive(minimumIncompleteLength: 20000, maximumLength: 200000) { [self] data, context, isComplete, error in receiving = true /* Check what we have */ var message = "" if data != nil { message = String(decoding: data!, as: UTF8.self) } else { message = "" } // ERROR if let unwrappedError = error { print(" >>ERROR: received in \(#function) - \(unwrappedError)") receiving = false return } // NO DATA guard let data = data else { print(" >>NO DATA with context - \(String(describing: context))") receiving = false return } // NOT COMPLETE if !isComplete { print(" >>NOT COMPLETE with context - \(String(describing: context))") //return } // RECEIVED A MESSAGE if message != "" { self.messageReceived = data print(" ...received data - \(String(describing: context)) \(String(describing: data))") receiving = false connection.cancel() return } // keep receiving, self.receive(connection) } } } func respond(on connection: NWConnection) { let response = """ HTTP/1.1 200 OK Content-Length: 2 OK """ connection.send( content: response.data(using: .utf8), completion: .idempotent ) } func cancel() { self.listener?.cancel() self.listener = nil self.listening = false self.isReady = false print("listener disabled") } }
0
0
164
1w