@@ -22,20 +22,20 @@ namespace signalr
2222{
2323 std::shared_ptr<connection_impl> connection_impl::create (const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer)
2424 {
25- return connection_impl::create (url, trace_level, log_writer, nullptr , nullptr );
25+ return connection_impl::create (url, trace_level, log_writer, nullptr , nullptr , false );
2626 }
2727
2828 std::shared_ptr<connection_impl> connection_impl::create (const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
29- std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>(const signalr_client_config&)> websocket_factory)
29+ std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>(const signalr_client_config&)> websocket_factory, const bool skip_negotiation )
3030 {
3131 return std::shared_ptr<connection_impl>(new connection_impl (url, trace_level,
32- log_writer ? log_writer : std::make_shared<trace_log_writer>(), http_client, websocket_factory));
32+ log_writer ? log_writer : std::make_shared<trace_log_writer>(), http_client, websocket_factory, skip_negotiation ));
3333 }
3434
3535 connection_impl::connection_impl (const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
36- std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory)
36+ std::unique_ptr<http_client> http_client, std::unique_ptr<transport_factory> transport_factory, const bool skip_negotiation )
3737 : m_base_url(url), m_connection_state(connection_state::disconnected), m_logger(log_writer, trace_level), m_transport(nullptr ),
38- m_transport_factory (std::move(transport_factory)), m_message_received([](const std::string&) noexcept {}), m_disconnected([]() noexcept {})
38+ m_transport_factory (std::move(transport_factory)), m_skip_negotiation(skip_negotiation), m_message_received([](const std::string&) noexcept {}), m_disconnected([]() noexcept {})
3939 {
4040 if (http_client != nullptr )
4141 {
@@ -50,8 +50,8 @@ namespace signalr
5050 }
5151
5252 connection_impl::connection_impl (const std::string& url, trace_level trace_level, const std::shared_ptr<log_writer>& log_writer,
53- std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>(const signalr_client_config&)> websocket_factory)
54- : m_base_url(url), m_connection_state(connection_state::disconnected), m_logger(log_writer, trace_level), m_transport(nullptr ),
53+ std::shared_ptr<http_client> http_client, std::function<std::shared_ptr<websocket_client>(const signalr_client_config&)> websocket_factory, const bool skip_negotiation )
54+ : m_base_url(url), m_connection_state(connection_state::disconnected), m_logger(log_writer, trace_level), m_transport(nullptr ), m_skip_negotiation(skip_negotiation),
5555 m_message_received ([](const std::string&) noexcept {}), m_disconnected([]() noexcept {})
5656 {
5757 if (http_client != nullptr )
@@ -156,8 +156,68 @@ namespace signalr
156156 std::weak_ptr<connection_impl> weak_connection = shared_from_this ();
157157 const auto & token = m_disconnect_cts;
158158
159+ const auto transport_started = [weak_connection, callback, token](std::shared_ptr<transport> transport, std::exception_ptr exception)
160+ {
161+ auto connection = weak_connection.lock ();
162+ if (!connection)
163+ {
164+ callback (std::make_exception_ptr (signalr_exception (" connection no longer exists" )));
165+ return ;
166+ }
167+
168+ try
169+ {
170+ if (exception != nullptr )
171+ {
172+ std::rethrow_exception (exception);
173+ }
174+ token->throw_if_cancellation_requested ();
175+ }
176+ catch (const std::exception& e)
177+ {
178+ if (token->is_canceled ())
179+ {
180+ connection->m_logger .log (trace_level::info,
181+ " starting the connection has been canceled." );
182+ }
183+ else
184+ {
185+ connection->m_logger .log (trace_level::errors,
186+ std::string (" connection could not be started due to: " )
187+ .append (e.what ()));
188+ }
189+
190+ connection->m_transport = nullptr ;
191+ connection->change_state (connection_state::disconnected);
192+ connection->m_start_completed_event .cancel ();
193+ callback (std::current_exception ());
194+ return ;
195+ }
196+
197+ connection->m_transport = transport;
198+
199+ if (!connection->change_state (connection_state::connecting, connection_state::connected))
200+ {
201+ connection->m_logger .log (trace_level::errors,
202+ std::string (" internal error - transition from an unexpected state. expected state: connecting, actual state: " )
203+ .append (translate_connection_state (connection->get_connection_state ())));
204+
205+ assert (false );
206+ }
207+
208+ connection->m_start_completed_event .cancel ();
209+ callback (nullptr );
210+ };
211+
212+ if (m_skip_negotiation)
213+ {
214+ // TODO: check that the websockets transport is explicitly selected
215+
216+ return start_transport (url, transport_started);
217+ }
218+
159219 negotiate::negotiate (*m_http_client, url, m_signalr_client_config,
160- [callback, weak_connection, redirect_count, token, url](negotiation_response&& response, std::exception_ptr exception)
220+ [callback, weak_connection, redirect_count, token, url, transport_started ](negotiation_response&& response, std::exception_ptr exception)
161221 {
162222 auto connection = weak_connection.lock ();
163223 if (!connection)
@@ -236,58 +296,7 @@ namespace signalr
236296 return ;
237297 }
238298
239- connection->start_transport (url, [weak_connection, callback, token](std::shared_ptr<transport> transport, std::exception_ptr exception)
240- {
241- auto connection = weak_connection.lock ();
242- if (!connection)
243- {
244- callback (std::make_exception_ptr (signalr_exception (" connection no longer exists" )));
245- return ;
246- }
247-
248- try
249- {
250- if (exception != nullptr )
251- {
252- std::rethrow_exception (exception);
253- }
254- token->throw_if_cancellation_requested ();
255- }
256- catch (const std::exception& e)
257- {
258- if (token->is_canceled ())
259- {
260- connection->m_logger .log (trace_level::info,
261- " starting the connection has been canceled." );
262- }
263- else
264- {
265- connection->m_logger .log (trace_level::errors,
266- std::string (" connection could not be started due to: " )
267- .append (e.what ()));
268- }
269-
270- connection->m_transport = nullptr ;
271- connection->change_state (connection_state::disconnected);
272- connection->m_start_completed_event .cancel ();
273- callback (std::current_exception ());
274- return ;
275- }
276-
277- connection->m_transport = transport;
278-
279- if (!connection->change_state (connection_state::connecting, connection_state::connected))
280- {
281- connection->m_logger .log (trace_level::errors,
282- std::string (" internal error - transition from an unexpected state. expected state: connecting, actual state: " )
283- .append (translate_connection_state (connection->get_connection_state ())));
284-
285- assert (false );
286- }
287-
288- connection->m_start_completed_event .cancel ();
289- callback (nullptr );
290- });
299+ connection->start_transport (url, transport_started);
291300 });
292301 }
293302
0 commit comments