Change basic connection to DNS SRV lookup for master server failover

This commit is contained in:
oldmud0 2017-07-24 22:44:35 -05:00
parent 1fe290aa74
commit 294d2150d0
5 changed files with 87 additions and 4 deletions

View File

@ -12,6 +12,7 @@
AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
{
net_manager = new NetworkManager(this);
QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool)), SLOT(ms_connect_finished(bool)));
}
AOApplication::~AOApplication()
@ -134,3 +135,20 @@ void AOApplication::loading_cancelled()
w_lobby->hide_loading_overlay();
}
void AOApplication::ms_connect_finished(bool connected)
{
if (connected)
{
AOPacket *f_packet = new AOPacket("ALL#%");
send_ms_packet(f_packet);
}
else
{
call_error("There was an error connecting to the master server.\n"
"We deploy multiple master servers to mitigate any possible downtime,"
"but the client appears to have exhausted all possible methods of finding"
"and connecting to one.\n"
"Please check your Internet connection and firewall, and please try again.");
}
}

View File

@ -146,6 +146,9 @@ private:
QVector<server_type> server_list;
QVector<server_type> favorite_list;
private slots:
void ms_connect_finished(bool connected);
public slots:
void server_disconnected();
void loading_cancelled();

View File

@ -14,8 +14,6 @@ int main(int argc, char *argv[])
AOApplication main_app(argc, argv);
main_app.construct_lobby();
main_app.net_manager->connect_to_master();
AOPacket *f_packet = new AOPacket("ALL#%");
main_app.send_ms_packet(f_packet);
main_app.w_lobby->show();
return main_app.exec();

View File

@ -27,7 +27,7 @@ void NetworkManager::connect_to_master()
ms_socket->close();
ms_socket->abort();
ms_socket->connectToHost(ms_hostname, ms_port);
perform_srv_lookup();
}
void NetworkManager::connect_to_server(server_type p_server)
@ -82,6 +82,59 @@ void NetworkManager::handle_ms_packet()
}
}
void NetworkManager::perform_srv_lookup()
{
ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_hostname, this);
connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup()));
ms_dns->lookup();
}
void NetworkManager::on_srv_lookup()
{
bool connected = false;
if (ms_dns->error() != QDnsLookup::NoError)
{
qWarning("SRV lookup of the master server DNS failed.");
ms_dns->deleteLater();
}
else
{
const auto srv_records = ms_dns->serviceRecords();
for (const QDnsServiceRecord &record : srv_records)
{
qDebug() << "Connecting to " << record.target();
ms_socket->connectToHost(record.target(), record.port());
QTime timer;
timer.start();
do
{
ao_app->processEvents();
if (ms_socket->state() == QAbstractSocket::ConnectedState)
{
connected = true;
break;
}
else if (ms_socket->error() != -1)
{
qWarning(QString("Error connecting to master server: %1").arg(ms_socket->errorString()).toStdString().c_str());
ms_socket->abort();
ms_socket->close();
break;
}
} while (timer.elapsed() < timeout_milliseconds); // Very expensive spin-wait loop - it will bring CPU to 100%!
if (connected) break;
else
{
ms_socket->abort();
ms_socket->close();
}
}
}
emit ms_connect_finished(connected);
}
void NetworkManager::handle_server_packet()
{
char buffer[16384] = {0};

View File

@ -5,6 +5,8 @@
#include "aoapplication.h"
#include <QTcpSocket>
#include <QDnsLookup>
#include <QTime>
class NetworkManager : public QObject
{
@ -17,9 +19,11 @@ public:
AOApplication *ao_app;
QTcpSocket *ms_socket;
QTcpSocket *server_socket;
QDnsLookup *ms_dns;
QString ms_hostname = "master.aceattorneyonline.com";
QString ms_hostname = "_aoms._tcp.aceattorneyonline.com";
int ms_port = 27016;
const int timeout_milliseconds = 2000;
bool ms_partial_packet = false;
QString ms_temp_packet = "";
@ -36,7 +40,14 @@ public slots:
void ship_ms_packet(QString p_packet);
void ship_server_packet(QString p_packet);
signals:
void ms_connect_finished(bool success);
private:
void perform_srv_lookup();
private slots:
void on_srv_lookup();
void handle_ms_packet();
void handle_server_packet();
};