Created
December 18, 2021 23:47
-
-
Save michael94ellis/92828bba252ccabd071279be098e26e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// UDPListener.swift | |
// | |
// Created by Michael Robert Ellis on 12/16/21. | |
// | |
import Foundation | |
import Network | |
import Combine | |
class UDPListener: ObservableObject { | |
var listener: NWListener? | |
var connection: NWConnection? | |
var queue = DispatchQueue.global(qos: .userInitiated) | |
/// New data will be place in this variable to be received by observers | |
@Published private(set) public var messageReceived: Data? | |
/// When there is an active listening NWConnection this will be `true` | |
@Published private(set) public var isReady: Bool = false | |
/// Default value `true`, this will become false if the UDPListener ceases listening for any reason | |
@Published public var listening: Bool = true | |
/// A convenience init using Int instead of NWEndpoint.Port | |
convenience init(on port: Int) { | |
self.init(on: NWEndpoint.Port(integerLiteral: NWEndpoint.Port.IntegerLiteralType(port))) | |
} | |
/// Use this init or the one that takes an Int to start the listener | |
init(on port: NWEndpoint.Port) { | |
let params = NWParameters.udp | |
params.allowFastOpen = true | |
self.listener = try? NWListener(using: params, on: port) | |
self.listener?.stateUpdateHandler = { update in | |
switch update { | |
case .ready: | |
self.isReady = true | |
print("Listener connected to port \(port)") | |
case .failed, .cancelled: | |
// Announce we are no longer able to listen | |
self.listening = false | |
self.isReady = false | |
print("Listener disconnected from port \(port)") | |
default: | |
print("Listener connecting to port \(port)...") | |
} | |
} | |
self.listener?.newConnectionHandler = { connection in | |
print("Listener receiving new message") | |
self.createConnection(connection: connection) | |
} | |
self.listener?.start(queue: self.queue) | |
} | |
func createConnection(connection: NWConnection) { | |
self.connection = connection | |
self.connection?.stateUpdateHandler = { (newState) in | |
switch (newState) { | |
case .ready: | |
print("Listener ready to receive message - \(connection)") | |
self.receive() | |
case .cancelled, .failed: | |
print("Listener failed to receive message - \(connection)") | |
// Cancel the listener, something went wrong | |
self.listener?.cancel() | |
// Announce we are no longer able to listen | |
self.listening = false | |
default: | |
print("Listener waiting to receive message - \(connection)") | |
} | |
} | |
self.connection?.start(queue: .global()) | |
} | |
func receive() { | |
self.connection?.receiveMessage { data, context, isComplete, error in | |
if let unwrappedError = error { | |
print("Error: NWError received in \(#function) - \(unwrappedError)") | |
return | |
} | |
guard isComplete, let data = data else { | |
print("Error: Received nil Data with context - \(String(describing: context))") | |
return | |
} | |
self.messageReceived = data | |
if self.listening { | |
self.receive() | |
} | |
} | |
} | |
func cancel() { | |
self.listening = false | |
self.connection?.cancel() | |
} | |
} |
Author
michael94ellis
commented
Aug 5, 2024
via email
I'm glad it helped!
…On Sat, Jun 15, 2024 at 8:49 AM Steve Splonskowski ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
Thank you Michael, the UDP listener code worked great for a project I am
considering that receives data from a piece of aviation hardware. Saved me
a bunch of time sort all of this out on my own.
—
Reply to this email directly, view it on GitHub
<https://gist.github.com/michael94ellis/92828bba252ccabd071279be098e26e6#gistcomment-5089789>
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AGEF4OCED2HOSJ5UK7M3S7DZHQZ5DBFKMF2HI4TJMJ2XIZLTSKBKK5TBNR2WLJDUOJ2WLJDOMFWWLO3UNBZGKYLEL5YGC4TUNFRWS4DBNZ2F6YLDORUXM2LUPGBKK5TBNR2WLJDHNFZXJJDOMFWWLK3UNBZGKYLEL52HS4DFVRZXKYTKMVRXIX3UPFYGLK2HNFZXIQ3PNVWWK3TUUZ2G64DJMNZZDAVEOR4XAZNEM5UXG5FFOZQWY5LFVEYTCMZWHA2TGNRYU52HE2LHM5SXFJTDOJSWC5DF>
.
You are receiving this email because you authored the thread.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>
.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment