27 class ClientSession :
public ETP_NS::AbstractSession
31 virtual ~ClientSession() =
default;
33 boost::asio::io_context& getIoContext() {
37 const std::string& getEtpServerHost()
const {
return etpServerHost; }
38 const std::string& getEtpServerPort()
const {
return etpServerPort; }
39 const std::string& getEtpServerTarget()
const {
return etpServerTarget; }
40 const std::string& getEtpServerAuthorization()
const {
return etpServerAuthorization; }
41 const std::string& getProxyHost()
const {
return proxyHost; }
42 const std::string& getProxyPort()
const {
return proxyPort; }
43 const std::string& getProxyAuthorization()
const {
return proxyAuthorization; }
54 resolver.async_resolve(
55 proxyHost.empty() ? etpServerHost : proxyHost,
56 proxyHost.empty() ? etpServerPort : proxyPort,
58 &ClientSession::on_resolve,
59 std::static_pointer_cast<ClientSession>(shared_from_this()),
60 std::placeholders::_1,
61 std::placeholders::_2));
68 if (!isCloseRequested_ && reconnectionTryCount_ < 10) {
69 ++reconnectionTryCount_;
70 std::cerr <<
"Session " <<
getIdentifier() <<
" has been disconnected, trying to reconnect... " << reconnectionTryCount_ <<
"/10" << std::endl;
71 getIoContext().restart();
75 if (!isCloseRequested_ && reconnectionTryCount_ >= 10) {
76 std::cerr <<
"Could not reconnect after 10 retries... Give up and close" << reconnectionTryCount_ <<
"/10" << std::endl;
77 isCloseRequested_ =
true;
81 void on_resolve(boost::system::error_code ec, tcp::resolver::results_type results) {
83 std::cerr <<
"on_resolve : " << ec.message() << std::endl;
86 asyncConnect(results);
89 virtual void asyncConnect(
const tcp::resolver::results_type& results) = 0;
91 virtual bool isTls()
const = 0;
93 void on_handshake(boost::system::error_code ec)
96 std::cerr <<
"on WS handshake, error code number : " << ec.value() << std::endl;
97 std::cerr <<
"on WS handshake, error message : " << ec.message() << std::endl;
98 std::cerr <<
"on WS handshake, error category : " << ec.category().name() << std::endl;
99 std::cerr <<
"Sometimes some ETP server require a trailing slash at the end of their URL. Did you also check your optional \"data-partition-id\" additional Header Field? Has your token expired?" << std::endl;
103 if (!responseType.count(boost::beast::http::field::sec_websocket_protocol) ||
104 responseType[boost::beast::http::field::sec_websocket_protocol] !=
"etp12.energistics.org")
105 std::cerr <<
"The client MUST specify the Sec-Websocket-Protocol header value of etp12.energistics.org, and the server MUST reply with the same" << std::endl;
107 fesapi_log(
"Now connected to Websocket");
108 webSocketSessionClosed =
false;
110 if (reconnectionTryCount_ > 0) {
111 auto resumeSession = std::make_shared<Energistics::Etp::v12::Protocol::CoreOSDU::ResumeSession>();
112 resumeSession->applicationName = requestSession->applicationName;
113 resumeSession->applicationVersion = requestSession->applicationVersion;
114 resumeSession->clientInstanceId = requestSession->clientInstanceId;
115 std::copy(identifier.begin(), identifier.end(), resumeSession->sessionId.array.begin());
116 send(resumeSession, 0, 0x02);
119 send(requestSession, 0, 0x02);
125 boost::asio::io_context ioc;
126 tcp::resolver resolver;
127 std::string etpServerHost;
128 std::string etpServerPort;
129 std::string etpServerTarget;
130 std::string etpServerAuthorization;
131 std::string proxyHost;
132 std::string proxyPort;
133 std::string proxyAuthorization;
134 std::map<std::string, std::string> additionalHandshakeHeaderFields_;
135 websocket::response_type responseType;
136 std::shared_ptr<Energistics::Etp::v12::Protocol::Core::RequestSession> requestSession;
145 InitializationParameters
const* initializationParams,
const std::string& target,
const std::string& etpServerAuth,
const std::string& proxyAuth =
"") :
148 etpServerHost(initializationParams->getEtpServerHost()),
149 etpServerPort(std::to_string(initializationParams->getEtpServerPort())),
150 etpServerTarget(target),
151 etpServerAuthorization(etpServerAuth),
152 proxyHost(initializationParams->getProxyHost()),
153 proxyPort(std::to_string(initializationParams->getProxyPort())),
154 proxyAuthorization(proxyAuth)
158 initializationParams->postSessionCreationOperation(
this);
161 requestSession = std::make_shared<Energistics::Etp::v12::Protocol::Core::RequestSession>();
162 requestSession->applicationName = initializationParams->getApplicationName();
163 requestSession->applicationVersion = initializationParams->getApplicationVersion();
165 std::copy(initializationParams->getInstanceId().begin(), initializationParams->getInstanceId().end(), requestSession->clientInstanceId.array.begin());
167 requestSession->requestedProtocols = initializationParams->makeSupportedProtocols();
168 requestSession->supportedDataObjects = initializationParams->makeSupportedDataObjects();
169 requestSession->supportedFormats.push_back(
"xml");
170 requestSession->currentDateTime = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
172 auto caps = initializationParams->makeEndpointCapabilities();
174 requestSession->endpointCapabilities = caps;
177 maxWebSocketMessagePayloadSize = initializationParams->getMaxWebSocketMessagePayloadSize();