27 const String& serviceDescription,
28 int broadcastPortToUse,
int connectionPort,
30 :
Thread (
"Discovery_broadcast"),
31 message (serviceTypeUID), broadcastPort (broadcastPortToUse),
32 minInterval (minTimeBetweenBroadcasts)
48void NetworkServiceDiscovery::Advertiser::run()
50 if (! socket.bindToPort (0))
56 while (! threadShouldExit())
59 wait ((
int) minInterval.inMilliseconds());
63void NetworkServiceDiscovery::Advertiser::sendBroadcast()
66 message.setAttribute (
"address", localAddress.toString());
68 auto data = message.createDocument ({},
true,
false);
69 socket.write (broadcastAddress.toString(), broadcastPort, data.toRawUTF8(), (
int) data.getNumBytesAsUTF8());
74 :
Thread (
"Discovery_listen"), serviceTypeUID (serviceType)
86void NetworkServiceDiscovery::AvailableServiceList::run()
88 while (! threadShouldExit())
90 if (socket.waitUntilReady (
true, 200) == 1)
93 auto bytesRead = socket.read (buffer,
sizeof (buffer) - 1,
false);
98 if (xml->hasTagName (serviceTypeUID))
102 removeTimedOutServices();
109 auto listCopy = services;
113void NetworkServiceDiscovery::AvailableServiceList::handleAsyncUpdate()
115 if (onChange !=
nullptr)
119void NetworkServiceDiscovery::AvailableServiceList::handleMessage (
const XmlElement& xml)
124 if (service.instanceID.trim().isNotEmpty())
131 handleMessage (service);
135static void sortServiceList (std::vector<NetworkServiceDiscovery::Service>& services)
137 auto compareServices = [] (
const NetworkServiceDiscovery::Service& s1,
138 const NetworkServiceDiscovery::Service& s2)
140 return s1.instanceID < s2.instanceID;
143 std::sort (services.begin(), services.end(), compareServices);
146void NetworkServiceDiscovery::AvailableServiceList::handleMessage (
const Service& service)
148 const ScopedLock sl (listLock);
150 for (
auto& s : services)
152 if (s.instanceID == service.instanceID)
154 if (s.description != service.description
155 || s.address != service.address
156 || s.port != service.port)
159 triggerAsyncUpdate();
162 s.lastSeen = service.lastSeen;
167 services.push_back (service);
168 sortServiceList (services);
169 triggerAsyncUpdate();
172void NetworkServiceDiscovery::AvailableServiceList::removeTimedOutServices()
174 const double timeoutSeconds = 5.0;
177 const ScopedLock sl (listLock);
179 auto oldEnd = std::end (services);
180 auto newEnd = std::remove_if (std::begin (services), oldEnd,
181 [=] (
const Service& s) {
return s.lastSeen < oldestAllowedTime; });
183 if (newEnd != oldEnd)
185 services.erase (newEnd, oldEnd);
186 triggerAsyncUpdate();
Wraps a pointer to a null-terminated UTF-8 character string, and provides various methods to operate ...
bool bindToPort(int localPortNumber)
Binds the socket to the specified local port.
Automatically locks and unlocks a mutex object.
Represents an IP address.
static IPAddress getLocalAddress(bool includeIPv6=false)
Returns the first 'real' address for the local machine.
static IPAddress getInterfaceBroadcastAddress(const IPAddress &interfaceAddress)
If the IPAdress is the address of an interface on the machine, returns the associated broadcast addre...
A relative measure of time.
static RelativeTime seconds(double seconds) noexcept
Creates a new RelativeTime object representing a number of seconds.
void startThread()
Starts the thread running.
static Time JUCE_CALLTYPE getCurrentTime() noexcept
Returns a Time object that is set to the current system time.
A universally unique 128-bit identifier.
Used to build a tree of elements representing an XML document.
int getIntAttribute(StringRef attributeName, int defaultReturnValue=0) const
Returns the value of a named attribute as an integer.
const String & getStringAttribute(StringRef attributeName) const noexcept
Returns the value of a named attribute.
void setAttribute(const Identifier &attributeName, const String &newValue)
Adds a named attribute to the element.
Advertiser(const String &serviceTypeUID, const String &serviceDescription, int broadcastPort, int connectionPort, RelativeTime minTimeBetweenBroadcasts=RelativeTime::seconds(1.5))
Creates and starts an Advertiser thread, broadcasting with the given properties.
~Advertiser() override
Destructor.
AvailableServiceList(const String &serviceTypeUID, int broadcastPort)
Creates an AvailableServiceList that will bind to the given port number and watch the network for Adv...
~AvailableServiceList() override
Destructor.
std::vector< Service > getServices() const
Returns a list of the currently known services.