ImagingTools Core SDK
CWebSocketClientComp.h
1// SPDX-License-Identifier: LGPL-2.1-or-later OR GPL-2.0-or-later OR GPL-3.0-or-later OR LicenseRef-ImtCore-Commercial
2#pragma once
3
4
5// Qt includes
6#include <QtWebSockets/QWebSocket>
7#include <QtCore/QTimer>
8#include <QtCore/QReadWriteLock>
9
10// ACF includes
11#include <ilog/TLoggerCompWrap.h>
12#include <istd/TPointerVector.h>
13#include <iprm/ITextParam.h>
14#include <imod/TModelWrap.h>
15#include <ibase/TRuntimeStatusHanderCompWrap.h>
16#include <iprm/IParamsSet.h>
17#include <iprm/IOptionsList.h>
18
19// ImtCore includes
20#include <imtcom/IServerConnectionInterface.h>
21#include <imtcom/IConnectionController.h>
22#include <imtcom/IConnectionStatusProvider.h>
23#include <imtrest/IRequestServlet.h>
24#include <imtrest/IProtocolEngine.h>
25#include <imtrest/ITransport.h>
26#include <imtrest/IResponseDispatcher.h>
27#include <imtclientgql/IGqlClient.h>
28#include <imtcom/ISslConfigurationManager.h>
29
30
31namespace imtclientgql
32{
33
34
35class CWebSocketClientCompBase:public ibase::TRuntimeStatusHanderCompWrap <ilog::CLoggerComponentBase>
36{
37public:
38 typedef ibase::TRuntimeStatusHanderCompWrap <ilog::CLoggerComponentBase> BaseClass;
39
40 I_BEGIN_COMPONENT(CWebSocketClientCompBase);
41 I_ASSIGN(m_sslConfigurationCompPtr, "SslConfiguration", "SSL Configuration is used by networking classes to relay information about an open SSL connection and to allow the server to control certain features of that connection.", false, "SslConfiguration")
42 I_ASSIGN_TO(m_sslConfigurationModelCompPtr, m_sslConfigurationCompPtr, false)
43 I_ASSIGN(m_sslConfigurationManagerCompPtr, "SslConfigurationManager", "SSL configuration manager, used to create an SSL configuration for server", false, "SslConfigurationManager")
44 I_ASSIGN(m_subprotocolListCompPtr, "Subprotocols", "Web Socket subprotocols", false, "Subprotocols");
45 I_END_COMPONENT;
46
47protected:
48 I_REF(iprm::IParamsSet, m_sslConfigurationCompPtr);
49 I_REF(imod::IModel, m_sslConfigurationModelCompPtr);
50 I_REF(imtcom::ISslConfigurationManager, m_sslConfigurationManagerCompPtr);
51 I_REF(iprm::IOptionsList, m_subprotocolListCompPtr);
52};
53
54class CWebSocketClientComp:
55 public QObject,
56 public CWebSocketClientCompBase,
57 virtual public imtrest::ITransport,
58 virtual public imtcom::IConnectionController,
59 virtual public imtrest::IResponseDispatcher,
60 virtual public IGqlClient,
61 private imod::CMultiModelDispatcherBase
62{
63 Q_OBJECT
64public:
65 typedef CWebSocketClientCompBase BaseClass;
66 typedef imod::CMultiModelDispatcherBase BaseClass2;
67
68 I_BEGIN_COMPONENT(CWebSocketClientComp);
69 I_REGISTER_INTERFACE(ITransport)
70 I_REGISTER_INTERFACE(IResponseDispatcher)
71 I_REGISTER_INTERFACE(imtcom::IConnectionController)
72 I_REGISTER_INTERFACE(imtclientgql::IGqlClient)
73 I_REGISTER_SUBELEMENT(ConnectionStatusProvider);
74 I_REGISTER_SUBELEMENT_INTERFACE_T(ConnectionStatusProvider, imtcom::IConnectionStatusProvider, ExtractConnectionStatusProvider);
75 I_REGISTER_SUBELEMENT_INTERFACE_T(ConnectionStatusProvider, istd::IChangeable, ExtractConnectionStatusProvider);
76 I_REGISTER_SUBELEMENT_INTERFACE_T(ConnectionStatusProvider, imod::IModel, ExtractConnectionStatusProvider);
77 I_ASSIGN(m_serverRequestHandlerCompPtr, "ServerRequestHandler", "Request handler registered for the server", false, "ServerRequestHandler");
78 I_ASSIGN(m_clientRequestHandlerCompPtr, "ClientRequestHandler", "Request handler registered for the client", false, "ClientRequestHandler");
79 I_ASSIGN(m_httpProtocolEngineCompPtr, "HttpProtocolEngine", "Http Protocol engine used in the http client", false, "ProtocolEngine");
80 I_ASSIGN(m_protocolEngineCompPtr, "ProtocolEngine", "Protocol engine used in the client", true, "ProtocolEngine");
81 I_ASSIGN(m_connectOnCreateAttrPtr, "ConnectOnCreate", "If enabled, the client will be connect to server on after component creation", true, true);
82 I_ASSIGN(m_serverConnectionCompPtr, "ServerConnectionInterface", "Parameter of the server communication interface", true, "ServerConnectionInterface");
83 I_ASSIGN(m_serverLoginAttrPtr, "ServerLoginParam", "Parameter providing the server login to be connected", false, "");
84 I_ASSIGN(m_serverPasswordAttrPtr, "ServerPasswordParam", "Parameter providing the server password to be connected", false, "");
85 I_ASSIGN(m_clientIdAttrPtr, "ClientId", "ID of the client that needs to be identified on the server", false, "");
86 I_ASSIGN(m_clientIdCompPtr, "ClientIdParam", "Parameter providing the client-ID that needs to be identified on the server", false, "ClientIdParam");
87 I_ASSIGN(m_productId, "ProductId", "Product-ID used with corresponded GraphQl requests", false, "");
88 I_END_COMPONENT;
89
90 CWebSocketClientComp();
91
92 // reimplemented (imtclientgql::IGqlClient)
93 virtual GqlResponsePtr SendRequest(GqlRequestPtr requestPtr, imtbase::IUrlParam* urlParamPtr = nullptr) const override;
94
95 // reimplemented (imtrest::ITransport)
96 virtual bool SendResponse(imtrest::ConstResponsePtr& response) const override;
97 virtual bool SendRequest(imtrest::ConstRequestPtr& request) const override;
98
99 // reimplemented (imtrest::IResponseDispatcher)
100 virtual bool SendResponse(const QByteArray& requestId, imtrest::ConstResponsePtr& response) const override;
101 virtual bool SendRequest(const QByteArray& requestId, imtrest::ConstRequestPtr& request) const override;
102
103 // reimplemented (imtcom::IConnectionController)
104 virtual bool Connect() override;
105 virtual bool Disconnect() override;
106
107protected:
108 QByteArray Sign(const QByteArray& message, const QByteArray& key = "") const;
109
110 // reimplemented (imod::CMultiModelDispatcherBase)
111 virtual void OnModelChanged(int modelId, const istd::IChangeable::ChangeSet& changeSet) override;
112
113 // reimplemented (ibase::TRuntimeStatusHanderCompWrap)
114 virtual void OnSystemShutdown() override;
115
116 // reimplemented (icomp::CComponentBase)
117 virtual void OnComponentCreated() override;
118 virtual void OnComponentDestroyed() override;
119
120Q_SIGNALS:
121 void EmitQueryDataReceived(int resultCode = 1);
122 void EmitWebSocketClose(
123 QWebSocketProtocol::CloseCode closeCode = QWebSocketProtocol::CloseCodeNormal,
124 const QString &reason = QString());
125 void EmitStopTimer();
126 void EmitStartTimer();
127 void EmitSendTextMessage(const QByteArray message) const;
128
129private Q_SLOTS:
130 void OnTimeout();
131 void OnWebSocketConnected();
132 void OnWebSocketDisconnected();
133 void OnWebSocketError(QAbstractSocket::SocketError error);
134 void OnSslErrors(const QList<QSslError>& sslErrors);
135 void OnWebSocketTextMessageReceived(const QString& message);
136 void OnWebSocketBinaryMessageReceived(const QByteArray& message);
137 void OnSendTextMessage(const QByteArray& message);
138
139protected:
140 virtual void EnsureWebSocketConnection();
141
142 class NetworkOperation
143 {
144 public:
145 NetworkOperation() = delete;
146 NetworkOperation(int timeout, const CWebSocketClientComp* parent);
147 ~NetworkOperation();
148
149 QEventLoop connectionLoop;
150 bool timerFlag;
151 QTimer timer;
152 };
153
154 class ConnectionStatusProvider:
156 {
157 public:
158 ConnectionStatusProvider();
159 virtual void SetConnectionStatus(ConnectionStatus status);
160
161 // reimplemented (imtcom::IConnectionStatusProvider)
162 virtual ConnectionStatus GetConnectionStatus() const override;
163
164 private:
165 ConnectionStatus m_connectionStatus;
166 };
167
168 template <typename InterfaceType>
169 static InterfaceType* ExtractConnectionStatusProvider(CWebSocketClientComp& component)
170 {
171 return &component.m_connectionStatusProvider;
172 }
173
174private:
175 I_REF(imtrest::IRequestServlet, m_serverRequestHandlerCompPtr);
176 I_REF(imtrest::IRequestServlet, m_clientRequestHandlerCompPtr);
177 I_REF(imtrest::IProtocolEngine, m_protocolEngineCompPtr);
178 I_REF(imtrest::IProtocolEngine, m_httpProtocolEngineCompPtr);
179 I_REF(imtcom::IServerConnectionInterface, m_serverConnectionCompPtr);
180 I_REF(iprm::ITextParam, m_webSocketServerLoginCompPtr);
181 I_REF(iprm::ITextParam, m_webSocketServerPasswordCompPtr);
182 I_REF(iprm::ITextParam, m_clientIdCompPtr);
183 I_ATTR(bool, m_connectOnCreateAttrPtr);
184 I_ATTR(QByteArray, m_serverLoginAttrPtr);
185 I_ATTR(QByteArray, m_serverPasswordAttrPtr);
186 I_ATTR(QByteArray, m_clientIdAttrPtr);
187 I_ATTR(QByteArray, m_productId);
188
189 mutable QWebSocket m_webSocket;
190 QTimer m_refreshTimer;
191 mutable QMap<QString, QByteArray> m_queryDataMap;
192 istd::TPointerVector<imtrest::IRequest> m_startQueries;
193 istd::TPointerVector<imtrest::IRequest> m_cacheQueries;
194 QAbstractSocket::SocketError m_lastSocketError;
195 mutable QReadWriteLock m_queryDataMapLock;
196
197 bool m_isInitialized = false;
198
199 imod::TModelWrap<ConnectionStatusProvider> m_connectionStatusProvider;
200};
201
202
203} // namespace imtclientgql
204
205
Simple interface for connection lifecycle control.
Interface for monitoring network connection status with observable state changes.
Interface for describing server connection configuration with multi-protocol support.
Server Communication and Connection Management Module.