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()
68 void NetworkServiceDiscovery::Advertiser::sendBroadcast()
71 message.
setAttribute (
"address", localAddress.toString());
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()
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()
132 void NetworkServiceDiscovery::AvailableServiceList::handleMessage (
const XmlElement& xml)
144 handleMessage (service);
148 static void sortServiceList (std::vector<NetworkServiceDiscovery::Service>& services)
156 std::sort (services.begin(), services.end(), compareServices);
159 void NetworkServiceDiscovery::AvailableServiceList::handleMessage (
const Service& service)
163 for (
auto& s : services)
168 || s.address != service.
address 169 || s.port != service.
port)
180 services.push_back (service);
181 sortServiceList (services);
185 void NetworkServiceDiscovery::AvailableServiceList::removeTimedOutServices()
187 const double timeoutSeconds = 5.0;
192 auto oldEnd = std::end (services);
193 auto newEnd = std::remove_if (std::begin (services), oldEnd,
196 if (newEnd != oldEnd)
198 services.erase (newEnd, oldEnd);
std::vector< Service > getServices() const
bool stopThread(int timeOutMilliseconds)
bool bindToPort(int localPortNumber)
bool isNotEmpty() const noexcept
void triggerAsyncUpdate()
int getIntAttribute(StringRef attributeName, int defaultReturnValue=0) const
static Time JUCE_CALLTYPE getCurrentTime() noexcept
std::function< void()> onChange
Advertiser(const String &serviceTypeUID, const String &serviceDescription, int broadcastPort, int connectionPort, RelativeTime minTimeBetweenBroadcasts=RelativeTime::seconds(1.5))
int64 inMilliseconds() const noexcept
static RelativeTime seconds(double seconds) noexcept
int waitUntilReady(bool readyForReading, int timeoutMsecs)
int read(void *destBuffer, int maxBytesToRead, bool blockUntilSpecifiedAmountHasArrived)
~AvailableServiceList() override
void setAttribute(const Identifier &attributeName, const String &newValue)
bool threadShouldExit() const
int write(const String &remoteHostname, int remotePortNumber, const void *sourceBuffer, int numBytesToWrite)
static IPAddress getLocalAddress(bool includeIPv6=false)
const String & getStringAttribute(StringRef attributeName) const noexcept
AvailableServiceList(const String &serviceTypeUID, int broadcastPort)
static IPAddress getInterfaceBroadcastAddress(const IPAddress &interfaceAddress)
bool wait(int timeOutMilliseconds) const
String toString(const TextFormat &format={}) const