### Use command-line tools for discovery Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Commands for installing and running the announce and listen binaries provided by the crate. ```bash # Install the crate cargo install simpdiscover # Or run from source cargo build --release # Start the announce binary to broadcast beacons # Default service name: "BeaconTestService" cargo run --bin announce # Announce with custom service name cargo run --bin announce -- MyCustomService # In another terminal, run the listen binary to discover services cargo run --bin listen # Listen for a specific service name cargo run --bin listen -- MyCustomService ``` -------------------------------- ### Implement full service discovery Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt A complete example showing how to run a BeaconSender in a background thread and listen for it in the main thread. ```rust use simpdiscoverylib::{BeaconSender, BeaconListener}; use std::time::Duration; use std::thread; fn main() -> std::io::Result<()> { let service_port: u16 = 15002; let broadcast_port: u16 = 9002; let my_service_name = "_my_service._tcp.local".as_bytes(); // Start the beacon sender in a background thread let sender = BeaconSender::new(service_port, my_service_name, broadcast_port) .expect("Could not create sender"); let sender_handle = thread::spawn(move || { println!("Starting beacon announcements..."); sender.send_loop(Duration::from_secs(1)) .expect("Send loop failed"); }); // In another process/thread, listen for the service let listener = BeaconListener::new(my_service_name, broadcast_port) .expect("Could not create listener"); println!("Waiting for service beacon..."); let beacon = listener.wait(Some(Duration::from_secs(30))) .expect("Timeout waiting for beacon"); println!("Service discovered!"); println!(" Name: {}", String::from_utf8_lossy(&beacon.service_name)); println!(" IP: {}", beacon.service_ip); println!(" Port: {}", beacon.service_port); // Verify the received data assert_eq!(beacon.service_name, my_service_name); assert_eq!(beacon.service_port, service_port); // Now connect to the service at beacon.service_ip:beacon.service_port let connection_string = format!("{}:{}", beacon.service_ip, beacon.service_port); println!("Ready to connect to: {}", connection_string); Ok(()) } ``` -------------------------------- ### Build and Test Steps Source: https://github.com/andrewdavidmackenzie/simpdiscover/blob/master/README.md Standard development workflow for the Simpdiscover crate, including building, testing, and linting. ```bash cd into the directory Add changes, add doc comments and/or doc tests and tests. cargo build cargo test cargo clippy -- -D warnings Create a PR ``` -------------------------------- ### Listen Binary Usage Source: https://github.com/andrewdavidmackenzie/simpdiscover/blob/master/README.md Run the 'listen' binary to wait for specific UDP broadcast beacons. An optional command-line parameter specifies the message to listen for before exiting. ```bash cargo run --bin listen -- Hello ``` -------------------------------- ### Announce Binary Usage Source: https://github.com/andrewdavidmackenzie/simpdiscover/blob/master/README.md Run the 'announce' binary to send UDP broadcast beacons. An optional command-line parameter can specify the beacon message string. ```bash cargo run --bin announce -- Hello ``` -------------------------------- ### Create BeaconSender Instance Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Instantiate `BeaconSender` to broadcast service announcements. Configure the service port, name, and the UDP port for broadcasting. The beacon payload includes a magic number, service port, and service name. ```rust use simpdiscoverylib::BeaconSender; use std::time::Duration; // Create a BeaconSender for a service named "my_database_service" running on port 5432 // Beacons will be broadcast on port 9002 let service_port: u16 = 5432; let service_name = "_my_database._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let beacon_sender = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Failed to create BeaconSender"); // The beacon payload format is: [magic_number(2 bytes)][service_port(2 bytes)][service_name(variable)] // Magic number is 0xbeef to identify valid simpdiscover beacons ``` -------------------------------- ### Inspect Beacon struct fields Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Demonstrates how to broadcast a service beacon and inspect the resulting Beacon struct fields upon discovery. ```rust use simpdiscoverylib::{BeaconSender, BeaconListener}; use std::time::Duration; use std::thread; // Beacon struct fields: // - service_ip: String - IP address the beacon was sent from // - service_port: u16 - Port the service is running on // - service_name: Vec - Name of the service (as bytes) let service_name = "_example._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let service_port: u16 = 8000; // Setup sender in background thread let sender = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Could not create sender"); thread::spawn(move || { sender.send_loop(Duration::from_secs(1)).ok(); }); // Receive and inspect beacon let listener = BeaconListener::new(service_name, broadcast_port) .expect("Could not create listener"); let beacon = listener.wait(Some(Duration::from_secs(5))) .expect("Failed to receive beacon"); // Access beacon fields assert_eq!(beacon.service_port, service_port); assert_eq!(beacon.service_name, service_name); println!("{}", beacon); // Uses Display trait: "ServiceName: '_example._tcp.local', Service IP: x.x.x.x, Service Port: 8000" ``` -------------------------------- ### BeaconListener::new Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Creates a new BeaconListener that binds to a specified port and filters incoming beacons by service name. It listens on `0.0.0.0` to receive UDP broadcast datagrams. ```APIDOC ## BeaconListener::new ### Description Creates a new `BeaconListener` that binds to the specified port and filters incoming beacons by service name. The listener binds to address `0.0.0.0` on the given port to receive UDP broadcast datagrams from any network interface. ### Method Associated function (constructor) ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use simpdiscoverylib::BeaconListener; // Create a listener that waits for beacons from "_my_database._tcp.local" service let service_name = "_my_database._tcp.local".as_bytes(); let listening_port: u16 = 9002; // Must match the broadcast port used by senders let listener = BeaconListener::new(service_name, listening_port) .expect("Could not create BeaconListener"); // Listener is now ready to receive beacons // Only beacons matching the service_name filter will be returned by wait() println!("Listener created, ready to receive beacons on port {}", listening_port); ``` ### Response #### Success Response (200) N/A (This is a library function, returns a Result) #### Response Example N/A ``` -------------------------------- ### Listen for a service with a timeout Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Executes the listener binary to wait for a specific service beacon within a defined timeout period. ```bash cargo run --bin listen -- MyCustomService 30 ``` -------------------------------- ### Create Beacon Listener Instance Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Initialize `BeaconListener` to receive UDP broadcast datagrams on a specified port. The listener filters incoming beacons based on the provided service name, binding to `0.0.0.0` to accept broadcasts from any network interface. ```rust use simpdiscoverylib::BeaconListener; // Create a listener that waits for beacons from "_my_database._tcp.local" service let service_name = "_my_database._tcp.local".as_bytes(); let listening_port: u16 = 9002; // Must match the broadcast port used by senders let listener = BeaconListener::new(service_name, listening_port) .expect("Could not create BeaconListener"); // Listener is now ready to receive beacons // Only beacons matching the service_name filter will be returned by wait() println!("Listener created, ready to receive beacons on port {}", listening_port); ``` -------------------------------- ### BeaconSender::new Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Creates a new BeaconSender instance to broadcast service announcements. It configures a UDP socket for broadcasting and prepares a beacon payload including a magic number, service port, and service name. ```APIDOC ## BeaconSender::new ### Description Creates a new `BeaconSender` instance configured to broadcast beacons for a specific service. The sender binds to a UDP socket, enables broadcast mode, and prepares a beacon payload containing a magic number, service port, and service name. ### Method Associated function (constructor) ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use simpdiscoverylib::BeaconSender; use std::time::Duration; // Create a BeaconSender for a service named "my_database_service" running on port 5432 // Beacons will be broadcast on port 9002 let service_port: u16 = 5432; let service_name = "_my_database._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let beacon_sender = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Failed to create BeaconSender"); // The beacon payload format is: [magic_number(2 bytes)][service_port(2 bytes)][service_name(variable)] // Magic number is 0xbeef to identify valid simpdiscover beacons ``` ### Response #### Success Response (200) N/A (This is a library function, returns a Result) #### Response Example N/A ``` -------------------------------- ### Beacon Struct Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Represents the data structure containing information about a discovered service. ```APIDOC ## Beacon Struct ### Description The Beacon struct contains information about a discovered service, including the IP address, port number, and service name. It implements Display for easy printing and logging. ### Fields - **service_ip** (String) - IP address the beacon was sent from - **service_port** (u16) - Port the service is running on - **service_name** (Vec) - Name of the service (as bytes) ``` -------------------------------- ### Run Beacon Sender in a Loop Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Utilize `send_loop` to continuously broadcast beacons at a set interval. This method blocks the current thread and is typically run in a separate thread to avoid halting the main application. ```rust use simpdiscoverylib::BeaconSender; use std::time::Duration; use std::thread; let service_port: u16 = 8080; let service_name = "_web_server._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let beacon = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Could not create sender"); // Spawn a background thread to send beacons every 5 seconds thread::spawn(move || { beacon.send_loop(Duration::from_secs(5)) .expect("Beacon send loop failed"); }); // Main application continues running... // The beacon thread will broadcast until the process exits println!("Service announced, main thread continues working..."); ``` -------------------------------- ### Wait for beacons with BeaconListener Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Blocks execution until a matching beacon is received or a timeout occurs. Requires a configured service name and broadcast port. ```rust use simpdiscoverylib::BeaconListener; use std::time::Duration; let service_name = "_cache_service._tcp.local".as_bytes(); let listener = BeaconListener::new(service_name, 9002) .expect("Could not create listener"); // Wait indefinitely for a beacon (blocking call) // let beacon = listener.wait(None).expect("Failed to receive beacon"); // Or wait with a 10-second timeout match listener.wait(Some(Duration::from_secs(10))) { Ok(beacon) => { println!("Discovered service!"); println!(" Service IP: {}", beacon.service_ip); println!(" Service Port: {}", beacon.service_port); println!(" Service Name: {}", String::from_utf8_lossy(&beacon.service_name)); // Connect to the discovered service let service_address = format!("{}:{}", beacon.service_ip, beacon.service_port); println!(" Connect to: {}", service_address); } Err(e) => { println!("Timeout or error waiting for beacon: {}", e); } } ``` -------------------------------- ### Send a Single Beacon Broadcast Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Use `send_one_beacon` for manual control over beacon transmission. This is useful for sending announcements on-demand, such as when a service's state changes. ```rust use simpdiscoverylib::BeaconSender; let service_port: u16 = 3000; let service_name = "_api_service._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let beacon = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Could not create sender"); // Send beacon when service becomes ready println!("Service ready, sending announcement..."); let bytes_sent = beacon.send_one_beacon() .expect("Failed to send beacon"); println!("Sent {} bytes as beacon", bytes_sent); // Later, send another beacon after a state change // beacon.send_one_beacon().expect("Failed to send beacon"); ``` -------------------------------- ### BeaconListener::wait Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Blocks and waits for a beacon matching the configured service name filter, returning a Beacon struct upon success. ```APIDOC ## BeaconListener::wait ### Description Blocks and waits for a beacon matching the configured service name filter. Accepts an optional timeout duration; if None, blocks indefinitely until a matching beacon is received. ### Parameters #### Arguments - **timeout** (Option) - Optional - The duration to wait for a beacon before timing out. If None, blocks indefinitely. ### Response - **Beacon** (struct) - Returns a Beacon struct containing the service IP, port, and name. ``` -------------------------------- ### BeaconSender::send_loop Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Enters an infinite loop to continuously send beacon broadcasts at a specified interval. This method blocks the current thread and is typically run in a separate thread. ```APIDOC ## BeaconSender::send_loop ### Description Enters an infinite loop that continuously sends beacon broadcasts at the specified time interval. This method blocks the current thread and runs until the process is terminated. Typically run in a separate thread to allow the main application to continue operating. ### Method Instance method ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use simpdiscoverylib::BeaconSender; use std::time::Duration; use std::thread; let service_port: u16 = 8080; let service_name = "_web_server._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let beacon = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Could not create sender"); // Spawn a background thread to send beacons every 5 seconds thread::spawn(move || { beacon.send_loop(Duration::from_secs(5)) .expect("Beacon send loop failed"); }); // Main application continues running... // The beacon thread will broadcast until the process exits println!("Service announced, main thread continues working..."); ``` ### Response #### Success Response (200) N/A (This is a library function, returns a Result) #### Response Example N/A ``` -------------------------------- ### BeaconSender::send_one_beacon Source: https://context7.com/andrewdavidmackenzie/simpdiscover/llms.txt Sends a single beacon broadcast to the network. This is useful for on-demand sending or when service state changes. ```APIDOC ## BeaconSender::send_one_beacon ### Description Sends a single beacon broadcast to the network. Useful when you want fine-grained control over when beacons are sent, such as sending a beacon only when a service state changes or on-demand rather than continuously. ### Method Instance method ### Endpoint N/A (This is a library function, not an HTTP endpoint) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use simpdiscoverylib::BeaconSender; let service_port: u16 = 3000; let service_name = "_api_service._tcp.local".as_bytes(); let broadcast_port: u16 = 9002; let beacon = BeaconSender::new(service_port, service_name, broadcast_port) .expect("Could not create sender"); // Send beacon when service becomes ready println!("Service ready, sending announcement..."); let bytes_sent = beacon.send_one_beacon() .expect("Failed to send beacon"); println!("Sent {} bytes as beacon", bytes_sent); // Later, send another beacon after a state change // beacon.send_one_beacon().expect("Failed to send beacon"); ``` ### Response #### Success Response (200) Returns the number of bytes sent. #### Response Example ``` Sent 42 bytes as beacon ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.