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