Refactor rehosting logic in FSD client

This commit is contained in:
Mat Sutcliffe
2023-03-12 18:23:53 +00:00
parent 6dc2492d29
commit dfc288bfd7
2 changed files with 43 additions and 65 deletions

View File

@@ -272,32 +272,6 @@ namespace BlackCore::Fsd
initiateConnection(); initiateConnection();
} }
void CFSDClient::handleVatsimServerIpResponse(QNetworkReply *nwReplyPtr)
{
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
const CServer s = this->getServer();
QString host = s.getAddress();
if (nwReply->error() == QNetworkReply::NoError)
{
QHostAddress addr(static_cast<QString>(nwReply->readAll()));
if (!addr.isNull()) { host = addr.toString(); }
}
if (m_rehosting)
{
m_rehosting_socket->connectToHost(host, m_socket->peerPort());
}
else
{
const quint16 port = static_cast<quint16>(s.getPort());
m_socket->connectToHost(host, port);
this->startPositionTimers();
}
}
void CFSDClient::disconnectFromServer() void CFSDClient::disconnectFromServer()
{ {
if (!CThreadUtils::isInThisThread(this)) if (!CThreadUtils::isInThisThread(this))
@@ -1677,62 +1651,71 @@ namespace BlackCore::Fsd
CLogMessage(this).info(u"Server requested we switch server to %1") << rehost.m_hostname; CLogMessage(this).info(u"Server requested we switch server to %1") << rehost.m_hostname;
Q_ASSERT_X(m_rehosting_host.isEmpty(), Q_FUNC_INFO, "Rehosting already in progress"); BLACK_AUDIT_X(!m_rehosting, Q_FUNC_INFO, "Rehosting already in progress");
Q_ASSERT_X(!m_rehosting_socket, Q_FUNC_INFO, "Rehosting already in progress");
m_rehosting_host = rehost.m_hostname;
m_rehosting = true; m_rehosting = true;
m_rehosting_socket = new QTcpSocket(this); auto rehostingSocket = std::make_shared<QTcpSocket>();
connect(m_rehosting_socket, &QTcpSocket::connected, this, [this] connect(rehostingSocket.get(), &QTcpSocket::connected, this, [this, rehostingSocket]
{ {
readDataFromSocket(); readDataFromSocket();
CLogMessage(this).debug(u"Successfully switched server"); CLogMessage(this).debug(u"Successfully switched server");
QObject::disconnect(m_rehosting_socket); m_socket = rehostingSocket;
m_socket.reset(m_rehosting_socket);
m_rehosting_socket = nullptr;
m_rehosting = false; m_rehosting = false;
m_rehosting_host = ""; rehostingSocket->disconnect(this);
connectSocketSignals(); connectSocketSignals();
readDataFromSocket(); readDataFromSocket();
}); });
connect(m_rehosting_socket, &QTcpSocket::errorOccurred, this, [this] connect(rehostingSocket.get(), &QTcpSocket::errorOccurred, this, [this, rehostingSocket]
{ {
CLogMessage(this).warning(u"Failed to switch server: %1") << m_rehosting_socket->errorString(); CLogMessage(this).warning(u"Failed to switch server: %1") << rehostingSocket->errorString();
m_rehosting = false; m_rehosting = false;
delete m_rehosting_socket; rehostingSocket->disconnect(this);
m_rehosting_host = "";
if (m_socket->state() != QAbstractSocket::ConnectedState) { updateConnectionStatus(CConnectionStatus::Disconnected); } if (m_socket->state() != QAbstractSocket::ConnectedState) { updateConnectionStatus(CConnectionStatus::Disconnected); }
}); });
initiateConnection(); initiateConnection(rehostingSocket, rehost.m_hostname);
} }
void CFSDClient::initiateConnection() void CFSDClient::initiateConnection(std::shared_ptr<QTcpSocket> rehostingSocket, const QString &rehostingHost)
{ {
const CServer s = this->getServer(); const CServer server = this->getServer();
const auto socket = rehostingSocket ? rehostingSocket : m_socket;
const QString host = rehostingSocket ? rehostingHost : server.getAddress();
const quint16 port = rehostingSocket ? m_socket->peerPort() : static_cast<quint16>(getServer().getPort());
QHostAddress serverAddress(m_rehosting ? m_rehosting_host : s.getAddress()); resolveLoadBalancing(host, [ = ](const QString &host)
{
socket->connectToHost(host, port);
if (!rehostingSocket) { this->startPositionTimers(); }
});
}
if (serverAddress.isNull() && (s.getName() == "AUTOMATIC" || m_rehosting) && s.getEcosystem() == CEcosystem::VATSIM) void CFSDClient::resolveLoadBalancing(const QString& host, std::function<void(const QString&)> callback)
{
if (QHostAddress(host).isNull() && (getServer().getName() == "AUTOMATIC" || m_rehosting) && getServer().getEcosystem() == CEcosystem::VATSIM)
{ {
// Not an IP -> Get IP for loadbalancing via HTTP // Not an IP -> Get IP for loadbalancing via HTTP
Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need app"); Q_ASSERT_X(sApp, Q_FUNC_INFO, "Need app");
CUrl url = sApp->getVatsimFsdHttpUrl(); CUrl url = sApp->getVatsimFsdHttpUrl();
sApp->getFromNetwork(url, { this, &CFSDClient::handleVatsimServerIpResponse }); sApp->getFromNetwork(url, { this, [ = ](QNetworkReply *nwReplyPtr)
{
QScopedPointer<QNetworkReply, QScopedPointerDeleteLater> nwReply(nwReplyPtr);
if (nwReply->error() == QNetworkReply::NoError)
{
QHostAddress addr(static_cast<QString>(nwReply->readAll()));
if (!addr.isNull())
{
callback(addr.toString());
return;
}
}
callback(host);
}});
} }
else else
{ {
if (m_rehosting) callback(host);
{
m_rehosting_socket->connectToHost(m_rehosting_host, m_socket->peerPort());
}
else
{
const QString host = s.getAddress();
const quint16 port = static_cast<quint16>(s.getPort());
m_socket->connectToHost(host, port);
this->startPositionTimers();
}
} }
} }

View File

@@ -389,8 +389,6 @@ namespace BlackCore::Fsd
void handleUnknownPacket(const QStringList &tokens); void handleUnknownPacket(const QStringList &tokens);
//! @} //! @}
void handleVatsimServerIpResponse(QNetworkReply *nwReplyPtr);
void printSocketError(QAbstractSocket::SocketError socketError); void printSocketError(QAbstractSocket::SocketError socketError);
void handleSocketError(QAbstractSocket::SocketError socketError); void handleSocketError(QAbstractSocket::SocketError socketError);
void handleSocketConnected(); void handleSocketConnected();
@@ -479,9 +477,11 @@ namespace BlackCore::Fsd
// Parser // Parser
QHash<QString, MessageType> m_messageTypeMapping; QHash<QString, MessageType> m_messageTypeMapping;
std::unique_ptr<QTcpSocket> m_socket = std::make_unique<QTcpSocket>(this); //!< used TCP socket, parent needed as it runs in worker thread std::shared_ptr<QTcpSocket> m_socket = std::make_shared<QTcpSocket>(this); //!< used TCP socket, parent needed as it runs in worker thread
void connectSocketSignals(); void connectSocketSignals();
void initiateConnection(); void initiateConnection(std::shared_ptr<QTcpSocket> rehostingSocket = {}, const QString &rehostingHost = {});
void resolveLoadBalancing(const QString &host, std::function<void(const QString &)> callback);
bool m_rehosting = false;
std::atomic_bool m_unitTestMode { false }; std::atomic_bool m_unitTestMode { false };
std::atomic_bool m_printToConsole { false }; std::atomic_bool m_printToConsole { false };
@@ -558,11 +558,6 @@ namespace BlackCore::Fsd
ServerType m_serverType = ServerType::LegacyFsd; ServerType m_serverType = ServerType::LegacyFsd;
Capabilities m_capabilities = Capabilities::None; Capabilities m_capabilities = Capabilities::None;
// Current rehosting
QTcpSocket* m_rehosting_socket = nullptr;
QString m_rehosting_host = "";
bool m_rehosting = false;
// buffered data for FSD // buffered data for FSD
BlackMisc::Aviation::CCallsign m_ownCallsign; //!< "buffered callsign", as this must not change when connected BlackMisc::Aviation::CCallsign m_ownCallsign; //!< "buffered callsign", as this must not change when connected
BlackMisc::Aviation::CCallsign m_partnerCallsign; //!< "buffered"callsign", of partner flying in shared cockpit BlackMisc::Aviation::CCallsign m_partnerCallsign; //!< "buffered"callsign", of partner flying in shared cockpit