Improve reliability of mDNS discovery

This commit is contained in:
Cameron Gutman 2019-08-04 18:04:07 -07:00
parent c6fd5cbbce
commit 1640bed7a5
2 changed files with 30 additions and 14 deletions

View File

@ -269,7 +269,7 @@ void ComputerManager::startPolling()
this, [this](const QMdnsEngine::Service& service) { this, [this](const QMdnsEngine::Service& service) {
qInfo() << "Discovered mDNS host:" << service.hostname(); qInfo() << "Discovered mDNS host:" << service.hostname();
MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(&m_MdnsServer, &m_MdnsCache, service); MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(&m_MdnsServer, service);
connect(pendingComputer, &MdnsPendingComputer::resolvedHost, connect(pendingComputer, &MdnsPendingComputer::resolvedHost,
this, &ComputerManager::handleMdnsServiceResolved); this, &ComputerManager::handleMdnsServiceResolved);
m_PendingResolution.append(pendingComputer); m_PendingResolution.append(pendingComputer);

View File

@ -21,13 +21,18 @@ class MdnsPendingComputer : public QObject
public: public:
explicit MdnsPendingComputer(QMdnsEngine::Server* server, explicit MdnsPendingComputer(QMdnsEngine::Server* server,
QMdnsEngine::Cache* cache,
const QMdnsEngine::Service& service) const QMdnsEngine::Service& service)
: m_Hostname(service.hostname()), : m_Hostname(service.hostname()),
m_Resolver(server, m_Hostname, cache) m_Server(server),
m_Resolver(nullptr)
{ {
connect(&m_Resolver, &QMdnsEngine::Resolver::resolved, // Start resolving
this, &MdnsPendingComputer::handleResolvedAddress); resolve();
}
virtual ~MdnsPendingComputer()
{
delete m_Resolver;
} }
QString hostname() QString hostname()
@ -38,28 +43,39 @@ public:
private slots: private slots:
void handleResolvedTimeout() void handleResolvedTimeout()
{ {
Q_ASSERT(!m_Addresses.isEmpty()); if (m_Addresses.isEmpty()) {
emit resolvedHost(this, m_Addresses); // Try again
qInfo() << "Resolving" << hostname() << "timed out. Retrying...";
resolve();
}
else {
Q_ASSERT(!m_Addresses.isEmpty());
emit resolvedHost(this, m_Addresses);
}
} }
void handleResolvedAddress(const QHostAddress& address) void handleResolvedAddress(const QHostAddress& address)
{ {
qInfo() << "Resolved" << hostname() << "to" << address; qInfo() << "Resolved" << hostname() << "to" << address;
m_Addresses.push_back(address); m_Addresses.push_back(address);
// Now that we got an address, start a timer to wait for more
// addresses to come in before reporting them
if (m_Addresses.count() == 1) {
QTimer::singleShot(1000, this, SLOT(handleResolvedTimeout()));
}
} }
signals: signals:
void resolvedHost(MdnsPendingComputer*,QVector<QHostAddress>&); void resolvedHost(MdnsPendingComputer*,QVector<QHostAddress>&);
private: private:
void resolve()
{
delete m_Resolver;
m_Resolver = new QMdnsEngine::Resolver(m_Server, m_Hostname);
connect(m_Resolver, &QMdnsEngine::Resolver::resolved,
this, &MdnsPendingComputer::handleResolvedAddress);
QTimer::singleShot(2000, this, SLOT(handleResolvedTimeout()));
}
QByteArray m_Hostname; QByteArray m_Hostname;
QMdnsEngine::Resolver m_Resolver; QMdnsEngine::Server* m_Server;
QMdnsEngine::Resolver* m_Resolver;
QVector<QHostAddress> m_Addresses; QVector<QHostAddress> m_Addresses;
}; };