diff --git a/README.md b/README.md index a78174d..2d646f0 100644 --- a/README.md +++ b/README.md @@ -107,4 +107,12 @@ qDebug() << zcs->txt["Qt"]; Qt5 -On Linux, libavahi-client-dev and libavahi-common-dev \ No newline at end of file +On Linux, libavahi-client-dev and libavahi-common-dev + +### Apple App Store deployment + +Publishing GPL software in the App Store is a [violation of the GPL](https://news.ycombinator.com/item?id=3488833). If you need to publish an app in the Apple App Store that uses QZeroConf, please contact me for a copy of QZeroConf with a BSD licence. + +### iOS device sleep + +When iOS puts the device to sleep, it breaks the DNS-SD browser and service publisher. The only way around this is to call stopServicePublish() and stopBrowser() when the application state changes to Qt::ApplicationSuspended (sleep) and then call startPublish() and startBrowser() when the application state changes to Qt::ApplicationActive (wake). See appStateChanged() in example. diff --git a/avahiclient.cpp b/avahiclient.cpp index 55ce737..9b4e45c 100644 --- a/avahiclient.cpp +++ b/avahiclient.cpp @@ -208,8 +208,10 @@ public: browser = NULL; QMap::iterator i; - for (i = pub->services.begin(); i != pub->services.end(); i++) + for (i = pub->services.begin(); i != pub->services.end(); i++) { + emit pub->serviceRemoved(*i); delete *i; + } pub->services.clear(); QMap::iterator r; @@ -269,6 +271,14 @@ void QZeroConf::stopServicePublish(void) } } +bool QZeroConf::publishExists(void) +{ + if (pri->group) + return true; + else + return false; +} + // http://www.zeroconf.org/rendezvous/txtrecords.html void QZeroConf::addServiceTxtRecord(QString nameOnly) @@ -312,3 +322,11 @@ void QZeroConf::stopBrowser(void) { pri->broswerCleanUp(); } + +bool QZeroConf::browserExists(void) +{ + if (pri->browser) + return true; + else + return false; +} diff --git a/avahicore.cpp b/avahicore.cpp index 04b7a91..091514b 100644 --- a/avahicore.cpp +++ b/avahicore.cpp @@ -220,8 +220,10 @@ public: browser = NULL; QMap::iterator i; - for (i = pub->services.begin(); i != pub->services.end(); i++) + for (i = pub->services.begin(); i != pub->services.end(); i++) { + emit pub->serviceRemoved(*i); delete *i; + } pub->services.clear(); QMap::iterator r; @@ -309,6 +311,14 @@ void QZeroConf::stopServicePublish(void) } } +bool QZeroConf::publishExists(void) +{ + if (pri->group) + return true; + else + return false; +} + // http://www.zeroconf.org/rendezvous/txtrecords.html void QZeroConf::addServiceTxtRecord(QString nameOnly) @@ -352,3 +362,11 @@ void QZeroConf::stopBrowser(void) { pri->broswerCleanUp(); } + +bool QZeroConf::browserExists(void) +{ + if (pri->browser) + return true; + else + return false; +} diff --git a/bonjour.cpp b/bonjour.cpp index 05d2b07..8dc4dd3 100644 --- a/bonjour.cpp +++ b/bonjour.cpp @@ -250,8 +250,10 @@ void QZeroConfPrivate::cleanUp(DNSServiceRef toClean) browserSocket = NULL; } QMap::iterator i; - for (i = pub->services.begin(); i != pub->services.end(); i++) + for (i = pub->services.begin(); i != pub->services.end(); i++) { + emit pub->serviceRemoved(*i); delete *i; + } pub->services.clear(); } else if (toClean == dnssRef) { @@ -318,6 +320,14 @@ void QZeroConf::stopServicePublish(void) pri->cleanUp(pri->dnssRef); } +bool QZeroConf::publishExists(void) +{ + if (pri->dnssRef) + return true; + else + return false; +} + void QZeroConf::addServiceTxtRecord(QString nameOnly) { pri->txt.append((quint8) nameOnly.size()); @@ -374,3 +384,11 @@ void QZeroConf::stopBrowser(void) { pri->cleanUp(pri->browser); } + +bool QZeroConf::browserExists(void) +{ + if (pri->browser) + return true; + else + return false; +} diff --git a/example/window.cpp b/example/window.cpp index f58e85f..757f4a9 100644 --- a/example/window.cpp +++ b/example/window.cpp @@ -24,6 +24,7 @@ Example app to demonstrate service publishing and service discovery --------------------------------------------------------------------------------------------------- **************************************************************************************************/ +#include #include #include #include @@ -54,9 +55,9 @@ mainWindow::mainWindow() connect(&zeroConf, SIGNAL(serviceAdded(QZeroConfService *)), this, SLOT(addService(QZeroConfService *))); connect(&zeroConf, SIGNAL(serviceRemoved(QZeroConfService *)), this, SLOT(removeService(QZeroConfService *))); + connect(qGuiApp, SIGNAL(applicationStateChanged(Qt::ApplicationState)), this, SLOT(appStateChanged(Qt::ApplicationState))); - zeroConf.startBrowser("_qtzeroconf_test._tcp"); - startPublish(); + publishEnabled = 1; } void mainWindow::buildGUI() @@ -68,13 +69,13 @@ void mainWindow::buildGUI() button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); layout->addWidget(button); layout->setAlignment(button, Qt::AlignHCenter); - connect(button, SIGNAL(clicked()), this, SLOT(startPublish())); + connect(button, &QPushButton::clicked, this, &mainWindow::startPublishClicked); button = new QPushButton(tr(" Disable Publish ")); button->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); layout->addWidget(button); layout->setAlignment(button, Qt::AlignHCenter); - connect(button, SIGNAL(clicked()), this, SLOT(stopPublish())); + connect(button, &QPushButton::clicked, this, &mainWindow::stopPublishClicked); table.verticalHeader()->hide(); table.horizontalHeader()->hide(); @@ -102,21 +103,39 @@ QString mainWindow::buildName(void) return name; } +void mainWindow::appStateChanged(Qt::ApplicationState state) +{ + if (state == Qt::ApplicationSuspended) { + zeroConf.stopServicePublish(); + zeroConf.stopBrowser(); + } + else if (state == Qt::ApplicationActive) { + if (publishEnabled && !zeroConf.publishExists()) + startPublish(); + if (!zeroConf.browserExists()) + zeroConf.startBrowser("_qtzeroconf_test._tcp"); + } +} + // ---------- Service Publish ---------- void mainWindow::startPublish() { - if (publishEnabled) - return; - publishEnabled = 1; - zeroConf.clearServiceTxtRecords(); zeroConf.addServiceTxtRecord("Qt", "the best!"); zeroConf.addServiceTxtRecord("ZeroConf is nice too"); zeroConf.startServicePublish(buildName().toUtf8(), "_qtzeroconf_test._tcp", "local", 11437); } -void mainWindow::stopPublish() +void mainWindow::startPublishClicked() +{ + if (publishEnabled) + return; + publishEnabled = 1; + startPublish(); +} + +void mainWindow::stopPublishClicked() { if (!publishEnabled) return; diff --git a/example/window.h b/example/window.h index b259b50..b4a53f1 100644 --- a/example/window.h +++ b/example/window.h @@ -40,14 +40,16 @@ public: private: void buildGUI(); + void startPublish(); QString buildName(void); QTableWidget table; QZeroConf zeroConf; bool publishEnabled; private slots: - void startPublish(); - void stopPublish(); + void appStateChanged(Qt::ApplicationState state); + void startPublishClicked(); + void stopPublishClicked(); void addService(QZeroConfService *item); void removeService(QZeroConfService *item); }; diff --git a/qzeroconf.h b/qzeroconf.h index e28a90a..54cd040 100644 --- a/qzeroconf.h +++ b/qzeroconf.h @@ -74,12 +74,14 @@ public: ~QZeroConf(); void startServicePublish(const char *name, const char *type, const char *domain, quint16 port); void stopServicePublish(void); + bool publishExists(void); inline void startBrowser(QString type) { startBrowser(type, QAbstractSocket::IPv4Protocol); } void startBrowser(QString type, QAbstractSocket::NetworkLayerProtocol protocol); void stopBrowser(void); + bool browserExists(void); void addServiceTxtRecord(QString nameOnly); void addServiceTxtRecord(QString name, QString value); void clearServiceTxtRecords();