mirror of
https://github.com/tnodir/fort
synced 2024-11-15 08:56:22 +00:00
RpcManager: Try to reconnect to service on error
This commit is contained in:
parent
997d1c5d0e
commit
8fd43d1b1a
@ -21,6 +21,8 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int maxClientsCount = 9;
|
||||
|
||||
const QLoggingCategory LC("control");
|
||||
|
||||
}
|
||||
@ -52,9 +54,9 @@ ControlWorker *ControlManager::newServiceClient(QObject *parent) const
|
||||
|
||||
connect(w, &ControlWorker::requestReady, this, &ControlManager::processRequest);
|
||||
|
||||
if (!w->connectToServer(getServerName(true))) {
|
||||
qCWarning(LC) << "Server connect error:" << socket->state() << socket->errorString();
|
||||
}
|
||||
w->setServerName(getServerName(/*isService=*/true));
|
||||
w->connectToServer();
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
@ -64,7 +66,7 @@ bool ControlManager::listen()
|
||||
|
||||
Q_ASSERT(!m_server);
|
||||
m_server = new QLocalServer(this);
|
||||
m_server->setMaxPendingConnections(3);
|
||||
m_server->setMaxPendingConnections(maxClientsCount);
|
||||
m_server->setSocketOptions(
|
||||
settings->isService() ? QLocalServer::WorldAccessOption : QLocalServer::NoOptions);
|
||||
|
||||
@ -94,10 +96,9 @@ bool ControlManager::postCommand()
|
||||
ControlWorker w(&socket);
|
||||
|
||||
// Connect to server
|
||||
if (!w.connectToServer(getServerName())) {
|
||||
qCWarning(LC) << "Connect to server error:" << socket.errorString();
|
||||
w.setServerName(getServerName(/*isService=*/false));
|
||||
if (!w.connectToServer())
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send data
|
||||
const QVariantList args = ControlWorker::buildArgs(settings->args());
|
||||
@ -110,9 +111,8 @@ bool ControlManager::postCommand()
|
||||
void ControlManager::onNewConnection()
|
||||
{
|
||||
while (QLocalSocket *socket = m_server->nextPendingConnection()) {
|
||||
constexpr int maxClientsCount = 9;
|
||||
if (m_clients.size() > maxClientsCount) {
|
||||
qCDebug(LC) << "Client dropped";
|
||||
qCDebug(LC) << "Client dropped: Count limit";
|
||||
delete socket;
|
||||
continue;
|
||||
}
|
||||
|
@ -76,7 +76,11 @@ bool parseArgsData(const QByteArray &buffer, QVariantList &args, bool compressed
|
||||
}
|
||||
|
||||
ControlWorker::ControlWorker(QLocalSocket *socket, QObject *parent) :
|
||||
QObject(parent), m_isServiceClient(false), m_isClientValidated(false), m_socket(socket)
|
||||
QObject(parent),
|
||||
m_isServiceClient(false),
|
||||
m_isClientValidated(false),
|
||||
m_isTryReconnect(false),
|
||||
m_socket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
@ -99,19 +103,35 @@ void ControlWorker::setupForAsync()
|
||||
{
|
||||
socket()->setParent(this);
|
||||
|
||||
connect(socket(), &QLocalSocket::disconnected, this, &ControlWorker::disconnected);
|
||||
connect(socket(), &QLocalSocket::errorOccurred, this,
|
||||
[&](QLocalSocket::LocalSocketError socketError) {
|
||||
qCWarning(LC) << "Client error:" << id() << socketError << errorString();
|
||||
close();
|
||||
});
|
||||
connect(socket(), &QLocalSocket::disconnected, this, &ControlWorker::onDisconnected);
|
||||
connect(socket(), &QLocalSocket::readyRead, this, &ControlWorker::processRequest);
|
||||
}
|
||||
|
||||
bool ControlWorker::connectToServer(const QString &name)
|
||||
void ControlWorker::setServerName(const QString &name)
|
||||
{
|
||||
socket()->connectToServer(name);
|
||||
return socket()->waitForConnected(100) && socket()->state() == QLocalSocket::ConnectedState;
|
||||
socket()->setServerName(name);
|
||||
}
|
||||
|
||||
bool ControlWorker::connectToServer()
|
||||
{
|
||||
socket()->connectToServer();
|
||||
|
||||
if (!socket()->waitForConnected(150)) {
|
||||
qCWarning(LC) << "Connection error:" << socket()->state() << socket()->errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (socket()->state() != QLocalSocket::ConnectedState) {
|
||||
qCWarning(LC) << "Connection state error:" << socket()->state();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ControlWorker::close()
|
||||
@ -120,6 +140,14 @@ void ControlWorker::close()
|
||||
socket()->close();
|
||||
}
|
||||
|
||||
void ControlWorker::onDisconnected()
|
||||
{
|
||||
if (isTryReconnect() && connectToServer())
|
||||
return;
|
||||
|
||||
emit disconnected();
|
||||
}
|
||||
|
||||
QByteArray ControlWorker::buildCommandData(Control::Command command, const QVariantList &args)
|
||||
{
|
||||
QByteArray data;
|
||||
|
@ -21,6 +21,9 @@ public:
|
||||
bool isClientValidated() const { return m_isClientValidated; }
|
||||
void setIsClientValidated(bool v) { m_isClientValidated = v; }
|
||||
|
||||
bool isTryReconnect() const { return m_isTryReconnect; }
|
||||
void setIsTryReconnect(bool v) { m_isTryReconnect = v; }
|
||||
|
||||
QLocalSocket *socket() const { return m_socket; }
|
||||
|
||||
int id() const;
|
||||
@ -29,7 +32,8 @@ public:
|
||||
|
||||
void setupForAsync();
|
||||
|
||||
bool connectToServer(const QString &name);
|
||||
void setServerName(const QString &name);
|
||||
bool connectToServer();
|
||||
|
||||
static QByteArray buildCommandData(Control::Command command, const QVariantList &args = {});
|
||||
bool sendCommandData(const QByteArray &commandData);
|
||||
@ -49,6 +53,7 @@ public slots:
|
||||
void close();
|
||||
|
||||
private slots:
|
||||
void onDisconnected();
|
||||
void processRequest();
|
||||
|
||||
private:
|
||||
@ -86,6 +91,7 @@ protected:
|
||||
private:
|
||||
bool m_isServiceClient : 1;
|
||||
bool m_isClientValidated : 1;
|
||||
bool m_isTryReconnect : 1;
|
||||
|
||||
RequestHeader m_requestHeader;
|
||||
QByteArray m_requestBuffer;
|
||||
|
@ -30,8 +30,6 @@ bool DriverManagerRpc::openDevice()
|
||||
|
||||
bool DriverManagerRpc::closeDevice()
|
||||
{
|
||||
IoC<RpcManager>()->client()->close();
|
||||
|
||||
updateState(0, false);
|
||||
|
||||
return false;
|
||||
|
@ -259,6 +259,11 @@ void RpcManager::setUp()
|
||||
}
|
||||
}
|
||||
|
||||
void RpcManager::tearDown()
|
||||
{
|
||||
closeClient();
|
||||
}
|
||||
|
||||
void RpcManager::setupServerSignals()
|
||||
{
|
||||
setupAppInfoManagerSignals();
|
||||
@ -363,9 +368,20 @@ void RpcManager::setupClient()
|
||||
auto controlManager = IoC()->setUpDependency<ControlManager>();
|
||||
|
||||
m_client = controlManager->newServiceClient(this);
|
||||
client()->setIsTryReconnect(true);
|
||||
|
||||
invokeOnServer(Control::Rpc_RpcManager_initClient);
|
||||
}
|
||||
|
||||
void RpcManager::closeClient()
|
||||
{
|
||||
if (!client())
|
||||
return;
|
||||
|
||||
client()->setIsTryReconnect(false);
|
||||
client()->close();
|
||||
}
|
||||
|
||||
bool RpcManager::waitResult()
|
||||
{
|
||||
m_resultCommand = Control::CommandNone;
|
||||
@ -384,17 +400,17 @@ void RpcManager::sendResult(ControlWorker *w, bool ok, const QVariantList &args)
|
||||
}
|
||||
|
||||
bool RpcManager::invokeOnServer(Control::Command cmd, const QVariantList &args)
|
||||
{
|
||||
return client()->sendCommand(cmd, args);
|
||||
}
|
||||
|
||||
bool RpcManager::doOnServer(Control::Command cmd, const QVariantList &args, QVariantList *resArgs)
|
||||
{
|
||||
if (!client()->isConnected()) {
|
||||
IoC<WindowManager>()->showErrorBox(tr("Service isn't available."));
|
||||
return false;
|
||||
}
|
||||
|
||||
return client()->sendCommand(cmd, args);
|
||||
}
|
||||
|
||||
bool RpcManager::doOnServer(Control::Command cmd, const QVariantList &args, QVariantList *resArgs)
|
||||
{
|
||||
if (!invokeOnServer(cmd, args))
|
||||
return false;
|
||||
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
ControlWorker *client() const { return m_client; }
|
||||
|
||||
void setUp() override;
|
||||
void tearDown() override;
|
||||
|
||||
bool waitResult();
|
||||
void sendResult(ControlWorker *w, bool ok, const QVariantList &args = {});
|
||||
@ -43,6 +44,7 @@ private:
|
||||
void setupTaskManagerSignals();
|
||||
|
||||
void setupClient();
|
||||
void closeClient();
|
||||
|
||||
void invokeOnClients(Control::Command cmd, const QVariantList &args = {});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user