Skip to content

Commit

Permalink
Always keep the same client around
Browse files Browse the repository at this point in the history
This fixes several race conditions with state handling
when multiple connection attempts are made.
  • Loading branch information
basyskom-jvoe committed Jul 11, 2024
1 parent b0f35f4 commit a009691
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 22 deletions.
46 changes: 26 additions & 20 deletions src/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ BackEnd::BackEnd(QObject *parent)
new CertificateItemModel(defaultPkiPath() % QStringLiteral("/own/certs/"), this)),
mLoggingViewModel(new LoggingViewModel(this)),
mOpcUaModel(new OpcUaModel(this)),
mOpcUaProvider(new QOpcUaProvider(this)),
mDashboardItemModel(new DashboardItemModel(this)),
mDefaultVariableDashboardsModel(new QStringListModel(this)),
mDefaultEventDashboardsModel(new QStringListModel(this)),
mSavedVariableDashboardsModel(new QStringListModel(this)),
mSavedEventDashboardsModel(new QStringListModel(this))
mSavedEventDashboardsModel(new QStringListModel(this)),
mOpcUaProvider(new QOpcUaProvider(this))
{
Logging::setLoggingViewModel(mLoggingViewModel);

Expand Down Expand Up @@ -112,6 +112,9 @@ BackEnd::~BackEnd()
if (isConnected()) {
saveLastDashboards();
}

if (mOpcUaClient)
mBackendMapping.remove(mOpcUaClient.get());
}

bool BackEnd::isConnected() const
Expand Down Expand Up @@ -248,7 +251,7 @@ BackEnd *BackEnd::getBackEndForNode(QOpcUaNode *node)

QOpcUaClient *BackEnd::getOpcUaClient()
{
return mOpcUaClient;
return mOpcUaClient.get();
}

void BackEnd::addDefaultVariableDashboard(const QString &name)
Expand Down Expand Up @@ -391,6 +394,10 @@ void BackEnd::connectToEndpoint()
authInfo.setUsernameAuthentication(mConnectionConfiguration.mUsername,
mConnectionConfiguration.mPassword);
mOpcUaClient->setAuthenticationInformation(authInfo);
} else {
QOpcUaAuthenticationInformation authInfo;
authInfo.setAnonymousAuthentication();
mOpcUaClient->setAuthenticationInformation(authInfo);
}

mOpcUaClient->connectToEndpoint(mConnectionConfiguration.mEndpoint);
Expand Down Expand Up @@ -781,7 +788,7 @@ void BackEnd::clientConnected()
qCDebug(backendLog) << "client connected";
setState(tr("client connected"));

connect(mOpcUaClient, &QOpcUaClient::namespaceArrayUpdated, this,
connect(mOpcUaClient.get(), &QOpcUaClient::namespaceArrayUpdated, this,
&BackEnd::namespacesArrayUpdated);
mOpcUaClient->updateNamespaceArray();
}
Expand All @@ -793,10 +800,6 @@ void BackEnd::clientDisconnected()

saveLastDashboards();
mDashboardItemModel->clearItems();

mOpcUaClient->deleteLater();
mBackendMapping.remove(mOpcUaClient);
mOpcUaClient = nullptr;
mOpcUaModel->setOpcUaClient(nullptr);
}

Expand All @@ -810,10 +813,10 @@ void BackEnd::namespacesArrayUpdated(const QStringList &namespaceArray)
findCompanionSpecObjects();

qCDebug(backendLog) << "namespace array updated" << namespaceArray;
disconnect(mOpcUaClient, &QOpcUaClient::namespaceArrayUpdated, this,
disconnect(mOpcUaClient.get(), &QOpcUaClient::namespaceArrayUpdated, this,
&BackEnd::namespacesArrayUpdated);

mOpcUaModel->setOpcUaClient(mOpcUaClient);
mOpcUaModel->setOpcUaClient(mOpcUaClient.get());
}

void BackEnd::clientError(QOpcUaClient::ClientError error)
Expand Down Expand Up @@ -852,18 +855,20 @@ void BackEnd::clientConnectError(QOpcUaErrorState *errorState)
void BackEnd::createClient()
{
if (mOpcUaClient == nullptr) {
mOpcUaClient = mOpcUaProvider->createClient(QStringLiteral("open62541"));
mOpcUaClient.reset(mOpcUaProvider->createClient(QStringLiteral("open62541")));
if (!mOpcUaClient) {
const QString message(tr("A possible cause could be that the backend "
"could not be loaded as a plugin."));
setState(tr("Failed to connect to server") % QChar::fromLatin1('\n') % message);
return;
}

mBackendMapping.insert(mOpcUaClient, this);
mBackendMapping.insert(mOpcUaClient.get(), this);

connect(mOpcUaClient, &QOpcUaClient::stateChanged, this, &BackEnd::connectionStateChanged);
connect(mOpcUaClient, &QOpcUaClient::connectError, this, &BackEnd::clientConnectError);
connect(mOpcUaClient.get(), &QOpcUaClient::stateChanged, this,
&BackEnd::connectionStateChanged);
connect(mOpcUaClient.get(), &QOpcUaClient::connectError, this,
&BackEnd::clientConnectError);

mOpcUaClient->setApplicationIdentity(mIdentity);
mOpcUaClient->setPkiConfiguration(mPkiConfig);
Expand All @@ -875,13 +880,14 @@ void BackEnd::createClient()
mOpcUaClient->setAuthenticationInformation(authInfo);
}

connect(mOpcUaClient, &QOpcUaClient::connected, this, &BackEnd::clientConnected);
connect(mOpcUaClient, &QOpcUaClient::disconnected, this, &BackEnd::clientDisconnected);
connect(mOpcUaClient, &QOpcUaClient::errorChanged, this, &BackEnd::clientError);
connect(mOpcUaClient, &QOpcUaClient::stateChanged, this, &BackEnd::clientState);
connect(mOpcUaClient, &QOpcUaClient::endpointsRequestFinished, this,
connect(mOpcUaClient.get(), &QOpcUaClient::connected, this, &BackEnd::clientConnected);
connect(mOpcUaClient.get(), &QOpcUaClient::disconnected, this,
&BackEnd::clientDisconnected);
connect(mOpcUaClient.get(), &QOpcUaClient::errorChanged, this, &BackEnd::clientError);
connect(mOpcUaClient.get(), &QOpcUaClient::stateChanged, this, &BackEnd::clientState);
connect(mOpcUaClient.get(), &QOpcUaClient::endpointsRequestFinished, this,
&BackEnd::getEndpointsComplete);
connect(mOpcUaClient, &QOpcUaClient::findServersFinished, this,
connect(mOpcUaClient.get(), &QOpcUaClient::findServersFinished, this,
&BackEnd::findServersComplete);
}
}
Expand Down
5 changes: 3 additions & 2 deletions src/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,6 @@ private slots:
LoggingViewModel *mLoggingViewModel;

OpcUaModel *mOpcUaModel;
QOpcUaProvider *mOpcUaProvider;
QOpcUaClient *mOpcUaClient = nullptr;
QOpcUaApplicationIdentity mIdentity;
QOpcUaPkiConfiguration mPkiConfig;

Expand Down Expand Up @@ -333,6 +331,9 @@ private slots:
QStringList mSelectedEventSourceNodes;

int mMaxEventsPerObject = 0;

QScopedPointer<QOpcUaProvider> mOpcUaProvider;
QScopedPointer<QOpcUaClient> mOpcUaClient;
};

#endif // BACKEND_H

0 comments on commit a009691

Please sign in to comment.