mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-06-18 14:40:56 +00:00
Implement mDNS PC discovery
This commit is contained in:
@@ -154,7 +154,8 @@ bool NvComputer::update(NvComputer& that)
|
|||||||
|
|
||||||
ComputerManager::ComputerManager(QObject *parent)
|
ComputerManager::ComputerManager(QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_Polling(false)
|
m_Polling(false),
|
||||||
|
m_MdnsBrowser(nullptr)
|
||||||
{
|
{
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
@@ -186,8 +187,25 @@ void ComputerManager::startPolling()
|
|||||||
{
|
{
|
||||||
QWriteLocker lock(&m_Lock);
|
QWriteLocker lock(&m_Lock);
|
||||||
|
|
||||||
|
if (m_Polling) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_Polling = true;
|
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);
|
QMapIterator<QString, NvComputer*> i(m_KnownHosts);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
i.next();
|
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()
|
QVector<NvComputer*> ComputerManager::getComputers()
|
||||||
{
|
{
|
||||||
QReadLocker lock(&m_Lock);
|
QReadLocker lock(&m_Lock);
|
||||||
@@ -229,8 +258,23 @@ void ComputerManager::stopPollingAsync()
|
|||||||
{
|
{
|
||||||
QWriteLocker lock(&m_Lock);
|
QWriteLocker lock(&m_Lock);
|
||||||
|
|
||||||
|
if (!m_Polling) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_Polling = false;
|
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
|
// Interrupt all threads, but don't wait for them to terminate
|
||||||
QMutableMapIterator<QString, QThread*> i(m_PollThreads);
|
QMutableMapIterator<QString, QThread*> i(m_PollThreads);
|
||||||
while (i.hasNext()) {
|
while (i.hasNext()) {
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "nvhttp.h"
|
#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 <QThread>
|
||||||
#include <QReadWriteLock>
|
#include <QReadWriteLock>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
@@ -207,6 +213,43 @@ private:
|
|||||||
NvComputer* m_Computer;
|
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
|
class ComputerManager : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -231,6 +274,8 @@ signals:
|
|||||||
private slots:
|
private slots:
|
||||||
void handleComputerStateChanged(NvComputer* computer);
|
void handleComputerStateChanged(NvComputer* computer);
|
||||||
|
|
||||||
|
void handleMdnsServiceResolved(MdnsPendingComputer* computer, const QHostAddress& address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void saveHosts();
|
void saveHosts();
|
||||||
|
|
||||||
@@ -240,4 +285,8 @@ private:
|
|||||||
QReadWriteLock m_Lock;
|
QReadWriteLock m_Lock;
|
||||||
QMap<QString, NvComputer*> m_KnownHosts;
|
QMap<QString, NvComputer*> m_KnownHosts;
|
||||||
QMap<QString, QThread*> m_PollThreads;
|
QMap<QString, QThread*> m_PollThreads;
|
||||||
|
QMdnsEngine::Server m_MdnsServer;
|
||||||
|
QMdnsEngine::Browser* m_MdnsBrowser;
|
||||||
|
QMdnsEngine::Cache m_MdnsCache;
|
||||||
|
QVector<MdnsPendingComputer*> m_PendingResolution;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user