The discovery bridge finds and advertises services on the local network over mDNS/Bonjour, SSDP/UPnP and WS-Discovery, backed by Shiny.Net.Discovery.
dotnet add package Shiny.AppDeviceBridge.Discovery
builder. UseAppDeviceBridge (
bridge => bridge. AddDiscoveryBridge (DiscoveryProtocols.All),
Client
C#
TypeScript
IDiscoveryBridge
AddDiscoveryBridgeClient()
DiscoveryBridge
Topic
Details
Searching
search returns everything seen during scanMs, 5 s by default and 30 s at most.
Browsing
each browse streams results as discovery.mdns, discovery.ssdp or discovery.wsd, so listen to that event first; without a listener it answers 409. At most 8 run at once, and a protocol’s browses stop once nothing listens to its event.
Publishing
publications keep advertising until deleted. At most 16.
Platform setup
on iOS and Mac Catalyst, list every browsed service type in NSBonjourServices and set NSLocalNetworkUsageDescription. On Android, SSDP and WS-Discovery need CHANGE_WIFI_MULTICAST_STATE.
A search collects answers for scanMs and returns them; a browse keeps going and streams them as events until you
stop it or nothing listens any more.
import { DiscoveryBridge } from "@shinyorg/appdevicebridge" ;
const discovery = new DiscoveryBridge ();
// one-shot: every printer that answers within 3 seconds
const printers = await discovery. searchMdns ({ serviceType: "_ipp._tcp" , resolveServices: true , scanMs: 3000 });
// continuous: services as they come and go
await discovery. onMdns ( r => r.status === "Found" ? add (r.service) : remove (r.service));
const browse = await discovery. browseMdns ({ serviceType: "_http._tcp" });
await discovery. stopBrowse (browse.id);
POST /_bridge/ discovery/mdns/searchThe mDNS services seen during the scan window, less any that went away. POST /_bridge/ discovery/mdns/browseBrowses for mDNS services; results arrive through onMdns. GET /_bridge/ discovery/mdns/resolveResolves one mDNS service. POST /_bridge/ discovery/mdns/publicationsAdvertises a service over mDNS. POST /_bridge/ discovery/ssdp/searchThe UPnP devices seen during the scan window, less any that went away. POST /_bridge/ discovery/ssdp/browseBrowses for UPnP devices; results arrive through onSsdp. GET /_bridge/ discovery/ssdp/descriptionA device's UPnP description. POST /_bridge/ discovery/ssdp/publicationsAdvertises a device over SSDP. POST /_bridge/ discovery/wsd/searchThe WS-Discovery targets seen during the scan window, less any that went away. POST /_bridge/ discovery/wsd/browseBrowses for WS-Discovery targets; results arrive through onWsd. GET /_bridge/ discovery/wsd/resolveResolves one WS-Discovery target. POST /_bridge/ discovery/wsd/publicationsAdvertises a target over WS-Discovery. GET /_bridge/ discovery/browsesThe running browses. DELETE /_bridge/ discovery/browses/{id} Stops a browse. GET /_bridge/ discovery/publicationsThe active publications. DELETE /_bridge/ discovery/publications/{id} Stops advertising, sending a goodbye so it vanishes from other devices straight away. POST /_bridge/ discovery/mdns/search# The mDNS services seen during the scan window, less any that went away.
C# IDiscoveryBridge.SearchMdnsAsyncTS DiscoveryBridge.searchMdns
Body application/json · MdnsSearchRequest MdnsSearchRequest · 4 fields serviceTypestring Such as _http._tcp. domainstring | null local. when null.resolveServicesboolean Resolve host, port, addresses and TXT records for each service found. scanMsnumber | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse.
Response 200 MdnsService []MdnsService · 9 fields instanceNamestring serviceTypestring domainstring fullNamestring hostNamestring | null portnumber addressesstring []txtRecordsRecord < ;string , string > ;isResolvedboolean
POST /_bridge/ discovery/mdns/browse# Browses for mDNS services; results arrive through onMdns.
C# IDiscoveryBridge.BrowseMdnsAsyncTS DiscoveryBridge.browseMdns
Body application/json · MdnsSearchRequest MdnsSearchRequest · 4 fields serviceTypestring Such as _http._tcp. domainstring | null local. when null.resolveServicesboolean Resolve host, port, addresses and TXT records for each service found. scanMsnumber | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse.
Response 200 DiscoveryBrowse DiscoveryBrowse · 3 fields idstring protocolDiscoveryProtocol targetstring What is being browsed for: a service type, search target or type list.
GET /_bridge/ discovery/mdns/resolve# Resolves one mDNS service. Fails with 404 when it does not answer.
C# IDiscoveryBridge.ResolveMdnsAsyncTS DiscoveryBridge.resolveMdns
Parameter In Type instanceNamequery string required serviceTypequery string required timeoutMsquery number | null optional
Response 200 MdnsService MdnsService · 9 fields instanceNamestring serviceTypestring domainstring fullNamestring hostNamestring | null portnumber addressesstring []txtRecordsRecord < ;string , string > ;isResolvedboolean
Errors 404 Not foundPOST /_bridge/ discovery/mdns/publications# Advertises a service over mDNS. On iOS the type must be listed in NSBonjourServices.
C# IDiscoveryBridge.PublishMdnsAsyncTS DiscoveryBridge.publishMdns
Body application/json · MdnsPublishRequest MdnsPublishRequest · 5 fields instanceNamestring serviceTypestring portnumber 1–65535. domainstring | null txtRecordsRecord < ;string , string > ; | null
Response 200 DiscoveryPublication DiscoveryPublication · 3 fields idstring protocolDiscoveryProtocol namestring The name in use, which mDNS may have changed to settle a conflict on the network.
POST /_bridge/ discovery/ssdp/search# The UPnP devices seen during the scan window, less any that went away.
C# IDiscoveryBridge.SearchSsdpAsyncTS DiscoveryBridge.searchSsdp
Body application/json · SsdpSearchRequest SsdpSearchRequest · 3 fields searchTargetstring | null ssdp:all when null.scanMsnumber | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse. maxWaitMsnumber | null How long devices may wait before answering, 1,000–5,000 ms.
Response 200 SsdpDevice []SsdpDevice · 9 fields udnstring locationstring | null serverstring | null notificationTypesstring []sourceAddressstring | null isRootDeviceboolean deviceTypestring | null serviceTypesstring []headersRecord < ;string , string > ;
POST /_bridge/ discovery/ssdp/browse# Browses for UPnP devices; results arrive through onSsdp.
C# IDiscoveryBridge.BrowseSsdpAsyncTS DiscoveryBridge.browseSsdp
Body application/json · SsdpSearchRequest SsdpSearchRequest · 3 fields searchTargetstring | null ssdp:all when null.scanMsnumber | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse. maxWaitMsnumber | null How long devices may wait before answering, 1,000–5,000 ms.
Response 200 DiscoveryBrowse DiscoveryBrowse · 3 fields idstring protocolDiscoveryProtocol targetstring What is being browsed for: a service type, search target or type list.
GET /_bridge/ discovery/ssdp/description# A device's UPnP description. The device must have been seen by a search or browse first; otherwise 404.
C# IDiscoveryBridge.GetSsdpDescriptionAsyncTS DiscoveryBridge.getSsdpDescription
Parameter In Type udnquery string required
Response 200 UpnpDeviceDescription UpnpDeviceDescription · 15 fields udnstring | null deviceTypestring | null friendlyNamestring | null manufacturerstring | null manufacturerUrlstring | null modelNamestring | null modelNumberstring | null modelDescriptionstring | null modelUrlstring | null serialNumberstring | null upcstring | null presentationUrlstring | null iconsUpnpIcon []servicesUpnpService []devicesUpnpDeviceDescription []
Errors 404 Not foundPOST /_bridge/ discovery/ssdp/publications# Advertises a device over SSDP.
C# IDiscoveryBridge.PublishSsdpAsyncTS DiscoveryBridge.publishSsdp
Body application/json · SsdpPublishRequest SsdpPublishRequest · 7 fields udnstring locationstring The absolute URL of the device description XML. deviceTypestring | null serviceTypesstring [] | null isRootDeviceboolean maxAgeSecondsnumber | null serverstring | null
Response 200 DiscoveryPublication DiscoveryPublication · 3 fields idstring protocolDiscoveryProtocol namestring The name in use, which mDNS may have changed to settle a conflict on the network.
POST /_bridge/ discovery/wsd/search# The WS-Discovery targets seen during the scan window, less any that went away.
C# IDiscoveryBridge.SearchWsdAsyncTS DiscoveryBridge.searchWsd
Body application/json · WsdSearchRequest WsdSearchRequest · 5 fields typesWsdQualifiedName [] | null scopesstring [] | null scopeMatchBystring | null profilesWsDiscoveryProfile scanMsnumber | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse.
Response 200 WsdTarget []WsdTarget · 9 fields endpointReferencestring typesWsdQualifiedName []scopesstring []addressesstring []preferredAddressstring | null metadataVersionnumber sourceAddressstring | null profileWsDiscoveryProfile isOnvifCameraboolean
POST /_bridge/ discovery/wsd/browse# Browses for WS-Discovery targets; results arrive through onWsd.
C# IDiscoveryBridge.BrowseWsdAsyncTS DiscoveryBridge.browseWsd
Body application/json · WsdSearchRequest WsdSearchRequest · 5 fields typesWsdQualifiedName [] | null scopesstring [] | null scopeMatchBystring | null profilesWsDiscoveryProfile scanMsnumber | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse.
Response 200 DiscoveryBrowse DiscoveryBrowse · 3 fields idstring protocolDiscoveryProtocol targetstring What is being browsed for: a service type, search target or type list.
GET /_bridge/ discovery/wsd/resolve# Resolves one WS-Discovery target. Fails with 404 when it does not answer.
C# IDiscoveryBridge.ResolveWsdAsyncTS DiscoveryBridge.resolveWsd
Parameter In Type endpointReferencequery string required timeoutMsquery number | null optional
Response 200 WsdTarget WsdTarget · 9 fields endpointReferencestring typesWsdQualifiedName []scopesstring []addressesstring []preferredAddressstring | null metadataVersionnumber sourceAddressstring | null profileWsDiscoveryProfile isOnvifCameraboolean
Errors 404 Not foundPOST /_bridge/ discovery/wsd/publications# Advertises a target over WS-Discovery.
C# IDiscoveryBridge.PublishWsdAsyncTS DiscoveryBridge.publishWsd
Body application/json · WsdPublishRequest WsdPublishRequest · 6 fields endpointReferencestring typesWsdQualifiedName [] | null scopesstring [] | null addressesstring [] | null Absolute URLs the target answers at. metadataVersionnumber profilesWsDiscoveryProfile
Response 200 DiscoveryPublication DiscoveryPublication · 3 fields idstring protocolDiscoveryProtocol namestring The name in use, which mDNS may have changed to settle a conflict on the network.
GET /_bridge/ discovery/browses# The running browses.
C# IDiscoveryBridge.GetBrowsesAsyncTS DiscoveryBridge.getBrowses
Response 200 DiscoveryBrowse []DiscoveryBrowse · 3 fields idstring protocolDiscoveryProtocol targetstring What is being browsed for: a service type, search target or type list.
DELETE /_bridge/ discovery/browses/{id} # Stops a browse.
C# IDiscoveryBridge.StopBrowseAsyncTS DiscoveryBridge.stopBrowse
Parameter In Type idpath string required
Response 204 No contentGET /_bridge/ discovery/publications# The active publications.
C# IDiscoveryBridge.GetPublicationsAsyncTS DiscoveryBridge.getPublications
Response 200 DiscoveryPublication []DiscoveryPublication · 3 fields idstring protocolDiscoveryProtocol namestring The name in use, which mDNS may have changed to settle a conflict on the network.
DELETE /_bridge/ discovery/publications/{id} # Stops advertising, sending a goodbye so it vanishes from other devices straight away.
C# IDiscoveryBridge.UnpublishAsyncTS DiscoveryBridge.unpublish
Parameter In Type idpath string required
Response 204 No content
An mDNS service was found or lost by a browse.
C# IDiscoveryBridge.OnMdnsAsyncTS DiscoveryBridge.onMdns
Payload MdnsBrowseResult A UPnP device was found or lost by a browse.
C# IDiscoveryBridge.OnSsdpAsyncTS DiscoveryBridge.onSsdp
Payload SsdpBrowseResult A WS-Discovery target was found or lost by a browse.
C# IDiscoveryBridge.OnWsdAsyncTS DiscoveryBridge.onWsd
Payload WsdBrowseResult A browse failed; onStopped follows.
C# IDiscoveryBridge.OnErrorAsyncTS DiscoveryBridge.onError
Payload DiscoveryError A browse ended.
C# IDiscoveryBridge.OnStoppedAsyncTS DiscoveryBridge.onStopped
Payload DiscoveryBrowse idstring protocolDiscoveryProtocol targetstring What is being browsed for: a service type, search target or type list.
JSON property names are camelCase and enums travel as their names. A ? marks a property the payload may omit;| null one that may be null.
serviceTypestring Such as _http._tcp. domain?string | null local. when null.resolveServices?boolean Resolve host, port, addresses and TXT records for each service found. scanMs?number | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse.
instanceNamestring serviceTypestring domainstring fullNamestring hostNamestring | null portnumber addressesstring []txtRecordsRecord < ;string , string > ;isResolvedboolean
idstring protocolDiscoveryProtocol targetstring What is being browsed for: a service type, search target or type list.
"Mdns""Ssdp""Wsd"
MdnsPublishRequestobject # instanceNamestring serviceTypestring portnumber 1–65535. domain?string | null txtRecords?Record < ;string , string > ; | null
DiscoveryPublicationobject # idstring protocolDiscoveryProtocol namestring The name in use, which mDNS may have changed to settle a conflict on the network.
searchTarget?string | null ssdp:all when null.scanMs?number | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse. maxWaitMs?number | null How long devices may wait before answering, 1,000–5,000 ms.
udnstring locationstring | null serverstring | null notificationTypesstring []sourceAddressstring | null isRootDeviceboolean deviceTypestring | null serviceTypesstring []headersRecord < ;string , string > ;
UpnpDeviceDescriptionobject # A device's UPnP description, with its embedded devices.
udnstring | null deviceTypestring | null friendlyNamestring | null manufacturerstring | null manufacturerUrlstring | null modelNamestring | null modelNumberstring | null modelDescriptionstring | null modelUrlstring | null serialNumberstring | null upcstring | null presentationUrlstring | null iconsUpnpIcon []servicesUpnpService []devicesUpnpDeviceDescription []
mimeTypestring | null widthnumber heightnumber depthnumber urlstring | null
serviceTypestring | null serviceIdstring | null scpdUrlstring | null controlUrlstring | null eventSubscriptionUrlstring | null
SsdpPublishRequestobject # udnstring locationstring The absolute URL of the device description XML. deviceType?string | null serviceTypes?string [] | null isRootDevice?boolean maxAgeSeconds?number | null server?string | null
types?WsdQualifiedName [] | null scopes?string [] | null scopeMatchBy?string | null profiles?WsDiscoveryProfile scanMs?number | null A search's window, 250–30,000 ms; 5 seconds when null. Ignored by a browse.
An XML qualified name, since WS-Discovery types are namespaced XML names.
namestring namespacestring
"None""Ws2005""Ws2009""All"
endpointReferencestring typesWsdQualifiedName []scopesstring []addressesstring []preferredAddressstring | null metadataVersionnumber sourceAddressstring | null profileWsDiscoveryProfile isOnvifCameraboolean
endpointReferencestring types?WsdQualifiedName [] | null scopes?string [] | null addresses?string [] | null Absolute URLs the target answers at. metadataVersion?number profiles?WsDiscoveryProfile
Whether a browse result is new or went away.
"Found""Lost"
These routes sit under AppDeviceBridgePolicies.Bridges like every other bridge: callers on this device by default.
See Security .