Change basic connection to DNS SRV lookup for master server failover
This commit is contained in:
		
							parent
							
								
									1fe290aa74
								
							
						
					
					
						commit
						294d2150d0
					
				@ -12,6 +12,7 @@
 | 
				
			|||||||
AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
 | 
					AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  net_manager = new NetworkManager(this);
 | 
					  net_manager = new NetworkManager(this);
 | 
				
			||||||
 | 
					  QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool)), SLOT(ms_connect_finished(bool)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AOApplication::~AOApplication()
 | 
					AOApplication::~AOApplication()
 | 
				
			||||||
@ -134,3 +135,20 @@ void AOApplication::loading_cancelled()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  w_lobby->hide_loading_overlay();
 | 
					  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.");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -146,6 +146,9 @@ private:
 | 
				
			|||||||
  QVector<server_type> server_list;
 | 
					  QVector<server_type> server_list;
 | 
				
			||||||
  QVector<server_type> favorite_list;
 | 
					  QVector<server_type> favorite_list;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private slots:
 | 
				
			||||||
 | 
					  void ms_connect_finished(bool connected);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public slots:
 | 
					public slots:
 | 
				
			||||||
  void server_disconnected();
 | 
					  void server_disconnected();
 | 
				
			||||||
  void loading_cancelled();
 | 
					  void loading_cancelled();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										2
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								main.cpp
									
									
									
									
									
								
							@ -14,8 +14,6 @@ int main(int argc, char *argv[])
 | 
				
			|||||||
    AOApplication main_app(argc, argv);
 | 
					    AOApplication main_app(argc, argv);
 | 
				
			||||||
    main_app.construct_lobby();
 | 
					    main_app.construct_lobby();
 | 
				
			||||||
    main_app.net_manager->connect_to_master();
 | 
					    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();
 | 
					    main_app.w_lobby->show();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return main_app.exec();
 | 
					    return main_app.exec();
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ void NetworkManager::connect_to_master()
 | 
				
			|||||||
  ms_socket->close();
 | 
					  ms_socket->close();
 | 
				
			||||||
  ms_socket->abort();
 | 
					  ms_socket->abort();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ms_socket->connectToHost(ms_hostname, ms_port);
 | 
					  perform_srv_lookup();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void NetworkManager::connect_to_server(server_type p_server)
 | 
					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()
 | 
					void NetworkManager::handle_server_packet()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  char buffer[16384] = {0};
 | 
					  char buffer[16384] = {0};
 | 
				
			||||||
 | 
				
			|||||||
@ -5,6 +5,8 @@
 | 
				
			|||||||
#include "aoapplication.h"
 | 
					#include "aoapplication.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QTcpSocket>
 | 
					#include <QTcpSocket>
 | 
				
			||||||
 | 
					#include <QDnsLookup>
 | 
				
			||||||
 | 
					#include <QTime>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NetworkManager : public QObject
 | 
					class NetworkManager : public QObject
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@ -17,9 +19,11 @@ public:
 | 
				
			|||||||
  AOApplication *ao_app;
 | 
					  AOApplication *ao_app;
 | 
				
			||||||
  QTcpSocket *ms_socket;
 | 
					  QTcpSocket *ms_socket;
 | 
				
			||||||
  QTcpSocket *server_socket;
 | 
					  QTcpSocket *server_socket;
 | 
				
			||||||
 | 
					  QDnsLookup *ms_dns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QString ms_hostname = "master.aceattorneyonline.com";
 | 
					  QString ms_hostname = "_aoms._tcp.aceattorneyonline.com";
 | 
				
			||||||
  int ms_port = 27016;
 | 
					  int ms_port = 27016;
 | 
				
			||||||
 | 
					  const int timeout_milliseconds = 2000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  bool ms_partial_packet = false;
 | 
					  bool ms_partial_packet = false;
 | 
				
			||||||
  QString ms_temp_packet = "";
 | 
					  QString ms_temp_packet = "";
 | 
				
			||||||
@ -36,7 +40,14 @@ public slots:
 | 
				
			|||||||
  void ship_ms_packet(QString p_packet);
 | 
					  void ship_ms_packet(QString p_packet);
 | 
				
			||||||
  void ship_server_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:
 | 
					private slots:
 | 
				
			||||||
 | 
					  void on_srv_lookup();
 | 
				
			||||||
  void handle_ms_packet();
 | 
					  void handle_ms_packet();
 | 
				
			||||||
  void handle_server_packet();
 | 
					  void handle_server_packet();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user