I'm working on an app that connects to a device on the same local WiFi.network. The device takes measurements and streams the data to the iPhone. The iPhone plots it in real time.
The problem I've run into is the iPhone delays the packets by up to 200ms every half second or so. This causes noticeable stutter in the UI that I'd like to eliminate.
I started debugging the issue by placing signposts in the code when packet is received.
Looking at the profiler, you can easily see the gaps in data.
Zooming in on the space after a gap, you can see a burst of packets received.
I've checked and it isn't dropping any packets. It is simply delaying them from my app.
The weird thing is this isn't an issue on the simulator or with the Android version of the app so I know it isn't an issue with the device or the WiFi.network.
Here is the same code running on the simulator showing a much more even distribution of packets.
Has anyone experienced anything like this? Is this just some kind of battery saving limitation of the iPhone hardware? Is there anyway to ensure a more timely delivery of the data to my application?
I tried rewriting the connection using SwiftNIO and ended up with the same results. I've also tried changing the serviceClass
parameter of the connection to all the possibilities with no change.
Here is the relevant connection code.
private func udpReceive() {
if udpConnection?.state == .ready {
udpConnection?.receive(minimumIncompleteLength: 1, maximumLength: Int(Hangboard.shared.BufferSize), completion: { content, contentContext, isComplete, error in
os_signpost(
.begin,
log: log,
name: "udpReceive",
signpostID: signpostID
)
Task {
if let content = content {
let _ = await asyncResult(for: Hangboard.shared.udpDataReceivedNative(data: content.toKotlinByteArray(), offset: 0, length: Int32(content.count)))
}
os_signpost(
.end,
log: log,
name: "udpReceive",
signpostID: signpostID
)
self.udpReceive()
}
})
} else {
disconnect(hadError: true)
}
}
private func startUdpListener(port: NWEndpoint.Port) {
let params = NWParameters.udp
params.allowFastOpen = true
params.serviceClass = .responsiveData
let listener = try? NWListener(using: params, on: port)
self.udpListener = listener
listener?.newConnectionLimit = 1
listener?.newConnectionHandler = { connection in
connection.parameters.serviceClass = .responsiveData
self.startUdpConnection(connection: connection)
}
listener?.start(queue: .global(qos: .userInteractive))
}
private func startUdpConnection(connection: NWConnection) {
self.udpConnection = connection
connection.stateUpdateHandler = { state in
switch state {
case .ready:
self.udpReceive()
case .failed(let error):
print("Connection error! \(error.localizedDescription)")
self.disconnect(hadError: true)
default:
break
}
}
connection.start(queue: .global(qos: .userInteractive))
}
Turns out the reason for this was because I was still running a Bonjour search in the background.
Disabling the search when connecting and restarting it on disconnect removed the latency issues.
Apple's tech support mentioned this can be a problem when includePeerToPeer
is enabled on a connection.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.