27 extern void acquireMulticastLock();
28 extern void releaseMulticastLock();
32 const String& serviceDescription,
33 int broadcastPortToUse,
int connectionPort,
35 :
Thread (
"Discovery_broadcast"),
36 message (serviceTypeUID), broadcastPort (broadcastPortToUse),
37 minInterval (minTimeBetweenBroadcasts)
53 void NetworkServiceDiscovery::Advertiser::run()
55 if (! socket.bindToPort (0))
61 while (! threadShouldExit())
64 wait ((
int) minInterval.inMilliseconds());
68 void NetworkServiceDiscovery::Advertiser::sendBroadcast()
71 message.setAttribute (
"address", localAddress.toString());
73 auto data = message.toString (XmlElement::TextFormat().singleLine().withoutHeader());
74 socket.write (broadcastAddress.toString(), broadcastPort, data.toRawUTF8(), (
int) data.getNumBytesAsUTF8());
79 :
Thread (
"Discovery_listen"), serviceTypeUID (serviceType)
82 acquireMulticastLock();
95 releaseMulticastLock();
99 void NetworkServiceDiscovery::AvailableServiceList::run()
101 while (! threadShouldExit())
103 if (socket.waitUntilReady (
true, 200) == 1)
106 auto bytesRead = socket.read (buffer,
sizeof (buffer) - 1,
false);
111 if (xml->hasTagName (serviceTypeUID))
112 handleMessage (*xml);
115 removeTimedOutServices();
122 auto listCopy = services;
126 void NetworkServiceDiscovery::AvailableServiceList::handleAsyncUpdate()
128 if (onChange !=
nullptr)
132 void NetworkServiceDiscovery::AvailableServiceList::handleMessage (
const XmlElement& xml)
137 if (service.instanceID.trim().isNotEmpty())
144 handleMessage (service);
148 static void sortServiceList (std::vector<NetworkServiceDiscovery::Service>& services)
150 auto compareServices = [] (
const NetworkServiceDiscovery::Service& s1,
151 const NetworkServiceDiscovery::Service& s2)
153 return s1.instanceID < s2.instanceID;
156 std::sort (services.begin(), services.end(), compareServices);
159 void NetworkServiceDiscovery::AvailableServiceList::handleMessage (
const Service& service)
161 const ScopedLock sl (listLock);
163 for (
auto& s : services)
165 if (s.instanceID == service.instanceID)
167 if (s.description != service.description
168 || s.address != service.address
169 || s.port != service.port)
172 triggerAsyncUpdate();
175 s.lastSeen = service.lastSeen;
180 services.push_back (service);
181 sortServiceList (services);
182 triggerAsyncUpdate();
185 void NetworkServiceDiscovery::AvailableServiceList::removeTimedOutServices()
187 const double timeoutSeconds = 5.0;
190 const ScopedLock sl (listLock);
192 auto oldEnd = std::end (services);
193 auto newEnd = std::remove_if (std::begin (services), oldEnd,
194 [=] (
const Service& s) {
return s.lastSeen < oldestAllowedTime; });
196 if (newEnd != oldEnd)
198 services.erase (newEnd, oldEnd);
199 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.