Local network discovery

Find a printer, discover a nearby app, or advertise a service your app already hosts. day-part-zeroconf uses DNS-based service discovery (DNS-SD) to report service names, addresses, ports, and TXT attributes. Discovery supplies connection information; your app chooses whether and how to connect.

Add to your app

Add day-part-zeroconf to your app’s Cargo dependencies:

[dependencies]
day-part-zeroconf = "0.1"

Crate · API reference · Source. Use the Day CLI to include mobile bridge code and permission metadata. No toolkit feature is required. Native service libraries and app permissions are described below.

Browse a service type

Use an async event loop rather than blocking the UI thread. This integration helper waits for one HTTP service; the caller decides whether to connect to it. _http._tcp is a protocol identifier, not a translated label.

use day_part_zeroconf::{BrowseOptions, Event, Result, Service, browse};

pub async fn first_http_service() -> Result<Option<Service>> {
    let mut operation = browse(BrowseOptions::service("_http._tcp"))?;
    while let Some(event) = operation.next_event().await {
        match event {
            Event::Resolved(service) => return Ok(Some(service)),
            Event::Error(error) => return Err(error),
            _ => {}
        }
    }
    Ok(None)
}

browse() returns an Operation. Keep it alive for continuing updates. Dropping it requests cancellation; its cancellation() handle lets a UI action cancel without blocking. The synchronous recv_timeout() and joining stop() belong on a worker thread.

OperationUse
BrowseOptions::service(type)Browse a known _name._tcp or _name._udp service in the local domain.
BrowseOptions::all()Enumerate types and browse them. An empty scan does not establish that no services exist.
resolve(id)Resolve an identity already known to the app.
advertise(service)Advertise an existing listener’s port and attributes. It does not start a server.

Identity, updates, and TXT data

A ServiceId includes the name, type, domain, and interface. Keep the whole identity when updating a list: the same instance can appear on several interfaces. Resolved events can repeat as addresses arrive; a removed event invalidates that observation. Preserve scope IDs on IPv6 link-local addresses. A service name or TXT record is not proof of a peer’s identity.

TxtRecord values are bytes. A key without a value differs from a key with an empty value. Publication rejects duplicate keys and limits each item to 255 bytes and the whole record to 1300 bytes. Check capabilities() for binary values, key-only values, and explicit interface selection. On event-queue overflow, stop the operation and restart with a narrower type.

Advertisement reports the actual registered name after native conflict handling. Linux may report a collision instead of choosing another name. Keep its operation alive while the listener is available, and drop it when the listener closes.

Platforms and permissions

PlatformSetup and limits
macOS / iOSBonjour. iOS needs declared service types and a localized local-network usage description. Arbitrary type enumeration on a physical iOS device also requires Apple’s multicast entitlement.
AndroidNsdManager. TXT publication uses UTF-8 strings; received values retain their bytes. The OS chooses the network.
Windows / WinUIDNS-SD APIs. Resolution is one-shot; browse or resolve again to refresh metadata.
Linux / GTK / QtAvahi, its client/common shared libraries, a running daemon, and system D-Bus.
HarmonyOSNative mDNS service. It chooses the interface, returns one address, and rejects key-only TXT publication.
WebUnsupported; browsers do not expose a general local-network DNS-SD API.

On Apple platforms, declare the intended service types and localized permission rationale in the native host configuration. A sandboxed macOS app also needs the network client/server entitlements appropriate to its operations. Declaring a capability does not grant an entitlement or user permission.

Android and HarmonyOS contribute network permissions through the crate’s metadata. Check requires_explicit_permission() and the crate’s host setup for the additional runtime permission requirements of the selected OS and target SDK.

Type enumeration on Android and HarmonyOS uses the default IPv4 multicast route. Targeted browsing is preferable on IPv6-only networks or when a responder does not advertise its type. Older Android, Windows, and HarmonyOS resolution needs explicit refresh for changing metadata.

Use HTTP or your app’s transport to connect after discovery, connectivity to observe network changes, and permissions for app permission handling.