Post

Replies

Boosts

Views

Activity

NWConnection endPoint info duplicated
I'm not native to networking so maybe I'm misunderstanding how endPoint information is gathered. Device_A is browsing and discovers Device_B or the other way around, it doesn't matter because they will both discover each other and send data to open a connection. Because the Network framework does not resolve ipAddresses, - https://developer.apple.com/forums/thread/129644 when a connection is first made I use either the remoteEndPoint (connection.currentPath?.remoteEndpoint // fe80::9821:7fff:fcea:74c4%awdl0.10059) or the endPoint description (connection.endpoint.debugDescription // myApp (2)._myApp._tcplocal.) as a uniqueID for the connection. I send the data and some other info across the wire, if successful I then place either endPoint inside an ivar dictionary as the key with another value so that I know which device to map a response to once a device responds back. Right now I only have 2 devices connected, the issue is when I receive a response from Device_B, I'm actually getting the incorrect endPoint information. For some reason I keep getting the endPoint info from Device_A back. It seems like the same endPoint information is getting sent twice. Once to Device_A and then again to Device_B. This exact same thing occurs on Device_B but in reverse. I'm confused as to why this is happening. For example Device_A first discovers itself, the remoteEndPoint is *fe80::9821:7fff:fcea:74c4%awdl0.10059*, it sends the data. When Device_A receives its own message, I filter it out using the userId and I see the same endPoint info. But when Device_A discovers Device_B, the remoteEndPoint is *fe80::9821:7fff:fcea:74c4%awdl0.27788*. When I receive a response from Device_B, the endPoint information is showing the first one from Device_A *fe80::9821:7fff:fcea:74c4%awdl0.10059*. The same remoteEndPoint info is duplicated. The same exact thing is happening if I use endpoint.debugDescription. This issue occurs on both devices. NWBrowser: browser.browseResultsChangedHandler = { (results, changes) in for change in changes { switch change { case .added(let browseResult): switch browseResult.endpoint { case .service(let name, let type,_,_): let connection = PeerConnection(to: browseResult.endpoint) // ... } PeerConnection: var connection: NWConnection? init(to endPoint: NWEndpoint) { // tcpOptions ... // params ... // initialize connection and delegate that sends out data connection.stateUpdateHandler = { (nwConnectionState) in case .ready: self.delegate.sendOutgoing(connection) } Send Data: var dict = [String:String]() var endPointArr = [String]() func sendOutgoing(_ connection: NWConnection) { let endPoint = connection.currentPath?.localEndpoint?.debugDescription or let endPoint = connection.currentPath?.remoteEndpoint?.debugDescription // encode the endPoint and currentUserId with some other info, then send it across the wire, if successful make the endPoint a key inside a dictionary and add it to an array to keep track of what endPoints were received connection.send(content: encodedData, contentContext: context, isComplete: true, completion: .contentProcessed({ [weak self](error) in { if let error = error { return } self?.dict[endPoint] = someUniqueValue self?.endPointArr.append(endPoint) })) } Receiving a response connection.receive(minimumIncompleteLength: 1, maximumLength: 65535) { [weak self](data, context, isComplete, error) { if let err = error { return } if let data = data, !data.isEmpty { self?.received(data) } } func received(_ data) { guard let retrievedData = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? MyModel else { return } guard let endPoint = retrievedData.endPoint as? String, let userID = retrievedData.userId as? String else { return } print(endPoint) // fe80::9821:7fff:fcea:74c4%awdl0.10059 if userID == Auth.auth().currentUser?.uid { dict[endPoint] = nil return } endPointArr.forEach { (endPoint) in print(endPoint) // prints both fe80::9821:7fff:fcea:74c4%awdl0.10059 and fe80::9821:7fff:fcea:74c4%awdl0.27788 } // this never runs because the key just got set to nil above because Device_B has the same endPoint info for (key, value) in dict where key == endpoint { print("key=\(key) : value=\(value)") // someUniqueValue // show response that this is a response from whichever device has this endPoint break } } [1]: https://developer.apple.com/forums/thread/129644
7
0
2.2k
Apr ’21
NWConnection -no Echo from connection.send(content: data, completion : .idempotent)
I'm using peer-to-peer and I successfully connect one client to another but when I send the echo to the individual connection the receiving client doesn't get a response. Initial send let data = NYKeyedArchiver.... let message = NWProtocolWebSocket.Metadata(opcode: .text) let context = NWConnection.ContentContext(identifier: "send",                                                   metadata: [message]) connection.send(content: data, contentContext: context, isComplete: true, completion: .contentProcessed({ (error) in if let error = error { return } print("Sent") })) Receive data and send Echo response func receivedIncoming(connection) { connection.receive(minimumIncompleteLength: 1, maximumLength: 65535) { (data, context, isComplete, error) in if let err = error { print(err) // never gets hit return } if let data = data, !data.isEmpty { // do something with data if let color = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? UIColor { // this should only run on the other device once echo is received after 5 secs         self?.view.backgroundColor = color } let randomColor = UIColor.random // func create random color        let colorData = randomColor.encode() // func encode color to data DispatchQueue.main.asyncAfter(deadline: .now() + 5) { connection.send(content: colorData, completion : .idempotent) // I've also tried let message = NWProtocolWebSocket.Metadata(opcode: .text)            let context = NWConnection.ContentContext(identifier: "send", metadata: [message]) connection.send(content: colorData, contentContext: context, isComplete: true, completion: .contentProcessed({ (error) in if let error = error { return } print("Color data sent") // this always prints })) } } else { print("data is empty") // never gets hit } } } NWConnection weak var delegate: PeerConnectionDelegate? var connection: NWConnection? // Outgoing Connection init(endPoint: NWEndpoint, delegate: PeerConnectionDelegate) { self.delegate = delegate let tcpOptions = NWProtocolTCP.Options() tcpOptions.enableKeepalive = true tcpOptions.keepaliveIdle = 2 let parameters = NWParameters(tls: nil, tcp: tcpOptions) parameters.includePeerToPeer = true parameters.allowLocalEndpointReuse = true connection = NWConnection(to: endPoint, using: parameters)     startOutgoingConnection() } // Incoming Connection init(connection: NWConnection, delegate: PeerConnectionDelegate) { self.delegate = delegate self.connection = connection startIncomingConnection() } func startIncomingConnection() { connection?.stateUpdateHandler = { (nwConnectionState) in case .ready:         self.delegate?.receivedIncoming(connection) // ... } Why is the echo data being sent but not received?
8
0
1.7k
Apr ’21