Implement mDNS PC discovery
This commit is contained in:
parent
7186f20e05
commit
5729f65138
2 changed files with 94 additions and 1 deletions
|
|
@ -154,7 +154,8 @@ bool NvComputer::update(NvComputer& that)
|
|||
|
||||
ComputerManager::ComputerManager(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_Polling(false)
|
||||
m_Polling(false),
|
||||
m_MdnsBrowser(nullptr)
|
||||
{
|
||||
QSettings settings;
|
||||
|
||||
|
|
@ -186,8 +187,25 @@ void ComputerManager::startPolling()
|
|||
{
|
||||
QWriteLocker lock(&m_Lock);
|
||||
|
||||
if (m_Polling) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Polling = true;
|
||||
|
||||
// Start an MDNS query for GameStream hosts
|
||||
m_MdnsBrowser = new QMdnsEngine::Browser(&m_MdnsServer, "_nvstream._tcp.local.", &m_MdnsCache);
|
||||
connect(m_MdnsBrowser, &QMdnsEngine::Browser::serviceAdded,
|
||||
this, [this](const QMdnsEngine::Service& service) {
|
||||
qDebug() << "Discovered mDNS host: " << service.hostname();
|
||||
|
||||
MdnsPendingComputer* pendingComputer = new MdnsPendingComputer(&m_MdnsServer, &m_MdnsCache, service);
|
||||
connect(pendingComputer, SIGNAL(resolvedv4(MdnsPendingComputer*,QHostAddress)),
|
||||
this, SLOT(handleMdnsServiceResolved(MdnsPendingComputer*,QHostAddress)));
|
||||
m_PendingResolution.append(pendingComputer);
|
||||
});
|
||||
|
||||
// Start polling threads for each known host
|
||||
QMapIterator<QString, NvComputer*> i(m_KnownHosts);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
|
|
@ -195,6 +213,17 @@ void ComputerManager::startPolling()
|
|||
}
|
||||
}
|
||||
|
||||
void ComputerManager::handleMdnsServiceResolved(MdnsPendingComputer* computer,
|
||||
const QHostAddress& address)
|
||||
{
|
||||
qDebug() << "Resolved " << computer->hostname() << " to " << address.toString();
|
||||
|
||||
addNewHost(address.toString(), true);
|
||||
|
||||
m_PendingResolution.removeOne(computer);
|
||||
computer->deleteLater();
|
||||
}
|
||||
|
||||
QVector<NvComputer*> ComputerManager::getComputers()
|
||||
{
|
||||
QReadLocker lock(&m_Lock);
|
||||
|
|
@ -229,8 +258,23 @@ void ComputerManager::stopPollingAsync()
|
|||
{
|
||||
QWriteLocker lock(&m_Lock);
|
||||
|
||||
if (!m_Polling) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_Polling = false;
|
||||
|
||||
// Delete machines that haven't been resolved yet
|
||||
while (!m_PendingResolution.isEmpty()) {
|
||||
MdnsPendingComputer* computer = m_PendingResolution.first();
|
||||
computer->deleteLater();
|
||||
m_PendingResolution.removeFirst();
|
||||
}
|
||||
|
||||
// Delete the browser to stop discovery
|
||||
delete m_MdnsBrowser;
|
||||
m_MdnsBrowser = nullptr;
|
||||
|
||||
// Interrupt all threads, but don't wait for them to terminate
|
||||
QMutableMapIterator<QString, QThread*> i(m_PollThreads);
|
||||
while (i.hasNext()) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,12 @@
|
|||
#pragma once
|
||||
#include "nvhttp.h"
|
||||
|
||||
#include <qmdnsengine/server.h>
|
||||
#include <qmdnsengine/cache.h>
|
||||
#include <qmdnsengine/browser.h>
|
||||
#include <qmdnsengine/service.h>
|
||||
#include <qmdnsengine/resolver.h>
|
||||
|
||||
#include <QThread>
|
||||
#include <QReadWriteLock>
|
||||
#include <QSettings>
|
||||
|
|
@ -207,6 +213,43 @@ private:
|
|||
NvComputer* m_Computer;
|
||||
};
|
||||
|
||||
class MdnsPendingComputer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MdnsPendingComputer(QMdnsEngine::Server* server,
|
||||
QMdnsEngine::Cache* cache,
|
||||
const QMdnsEngine::Service& service)
|
||||
: m_Hostname(service.hostname()),
|
||||
m_Resolver(server, m_Hostname, cache)
|
||||
{
|
||||
connect(&m_Resolver, SIGNAL(resolved(QHostAddress)),
|
||||
this, SLOT(handleResolved(QHostAddress)));
|
||||
}
|
||||
|
||||
QString hostname()
|
||||
{
|
||||
return m_Hostname;
|
||||
}
|
||||
|
||||
private slots:
|
||||
void handleResolved(const QHostAddress& address)
|
||||
{
|
||||
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||
m_Resolver.disconnect();
|
||||
emit resolvedv4(this, address);
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void resolvedv4(MdnsPendingComputer*, const QHostAddress&);
|
||||
|
||||
private:
|
||||
QByteArray m_Hostname;
|
||||
QMdnsEngine::Resolver m_Resolver;
|
||||
};
|
||||
|
||||
class ComputerManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -231,6 +274,8 @@ signals:
|
|||
private slots:
|
||||
void handleComputerStateChanged(NvComputer* computer);
|
||||
|
||||
void handleMdnsServiceResolved(MdnsPendingComputer* computer, const QHostAddress& address);
|
||||
|
||||
private:
|
||||
void saveHosts();
|
||||
|
||||
|
|
@ -240,4 +285,8 @@ private:
|
|||
QReadWriteLock m_Lock;
|
||||
QMap<QString, NvComputer*> m_KnownHosts;
|
||||
QMap<QString, QThread*> m_PollThreads;
|
||||
QMdnsEngine::Server m_MdnsServer;
|
||||
QMdnsEngine::Browser* m_MdnsBrowser;
|
||||
QMdnsEngine::Cache m_MdnsCache;
|
||||
QVector<MdnsPendingComputer*> m_PendingResolution;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue