Skip to content

Instantly share code, notes, and snippets.

@PatrickPijnappel
Last active October 10, 2021 07:31
Show Gist options
  • Save PatrickPijnappel/77e45cace7dc8f90b1c1075893c7444b to your computer and use it in GitHub Desktop.
Save PatrickPijnappel/77e45cace7dc8f90b1c1075893c7444b to your computer and use it in GitHub Desktop.
Network Lag STR
import UIKit
import Network
class ViewController: UIViewController {
var server: Server?
var client: Client?
override func viewDidLoad() {
super.viewDidLoad()
if UIDevice.current.userInterfaceIdiom == .pad {
server = Server()
} else {
client = Client()
}
}
}
class Server {
let queue = DispatchQueue(label: "Server.queue")
var connection: NWConnection?
var lastReceiveTime: Date?
init() {
let params: NWParameters = .udp
params.includePeerToPeer = true
let listener = try! NWListener(using: params)
listener.service = NWListener.Service(type: "_test._udp")
listener.newConnectionHandler = { connection in
print("Incoming connection")
self.handleConnection(connection)
}
listener.start(queue: queue)
print("Started listener")
}
private func handleConnection(_ connection: NWConnection) {
self.connection = connection
connection.start(queue: queue)
queue.async { self.receivePacket() }
}
private func receivePacket() {
guard let connection = connection else { return }
connection.receiveMessage(completion: { (data, _, _, _) in
guard data != nil else { return }
let now = Date()
let dt = Int(now.timeIntervalSince(self.lastReceiveTime ?? now)*1000)
NSLog("Received packet: \(dt)")
self.lastReceiveTime = now
if connection.state == .ready { self.receivePacket() }
})
}
}
class Client : NSObject, NetServiceBrowserDelegate, NetServiceDelegate {
let browser = NetServiceBrowser()
let queue = DispatchQueue(label: "Client.queue")
var service: NetService?
var connection: NWConnection?
var sendTimer: Timer?
var lastSendTime: Date?
override init() {
super.init()
browser.includesPeerToPeer = true
browser.delegate = self
browser.searchForServices(ofType: "_test._udp", inDomain: "local.")
print("Started searching")
}
func netServiceBrowser(_ browser: NetServiceBrowser, didFind service: NetService, moreComing: Bool) {
print("Found \(service)")
guard self.service == nil else { return }
self.service = service
service.delegate = self
service.resolve(withTimeout: 5)
}
func netServiceDidResolveAddress(_ service: NetService) {
print("Resolved \(service)")
guard let rawHost = service.hostName, let port = NWEndpoint.Port(rawValue: UInt16(service.port)) else { return }
let endpoint: NWEndpoint = .hostPort(host: NWEndpoint.Host(rawHost), port: port)
print("Connecting to \(endpoint) over UDP")
let params: NWParameters = .udp
params.includePeerToPeer = true
let connection = NWConnection(to: endpoint, using: params)
self.connection = connection
connection.stateUpdateHandler = { state in
print("Connection state: \(state)")
guard state == .ready else { return }
DispatchQueue.main.async {
self.sendTimer = Timer.scheduledTimer(withTimeInterval: 1/30, repeats: true) { _ in
let data = Data(count: 500)
connection.send(content: data, completion: .contentProcessed { _ in
let now = Date()
let dt = Int(now.timeIntervalSince(self.lastSendTime ?? now)*1000)
print("Sent packet: \(dt)")
self.lastSendTime = now
})
}
}
}
connection.start(queue: queue)
}
}
@saket
Copy link

saket commented Oct 8, 2021

Thanks for maintaining this @PatrickPijnappel. Do you know why is NWParameters#includePeerToPeer needed?

@PatrickPijnappel
Copy link
Author

IIRC it was to allow wifi connection between two devices with the actually being connect to a WiFi network (say outdoors)

@saket
Copy link

saket commented Oct 10, 2021

I see. Do you know if that's useful for Bonjour?

@PatrickPijnappel
Copy link
Author

I'm not sure, too long ago haha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment