@@ -85,6 +85,7 @@ class winrt_callback_client : public websocket_client_callback_impl, public std:
85
85
public:
86
86
winrt_callback_client (websocket_client_config config) :
87
87
websocket_client_callback_impl (std::move(config)),
88
+ m_connected (false ),
88
89
m_num_sends (0 )
89
90
{
90
91
m_msg_websocket = ref new MessageWebSocket ();
@@ -144,23 +145,26 @@ class winrt_callback_client : public websocket_client_callback_impl, public std:
144
145
145
146
~winrt_callback_client ()
146
147
{
147
- // Locally copy the task completion event since there is a PPL bug
148
- // that the set method accesses internal state in the event and the websocket
149
- // client could be destroyed.
150
- auto local_close_tce = m_close_tce;
151
- local_close_tce.set ();
148
+ // Only call close if successfully connected.
149
+ if (m_connected)
150
+ {
151
+ // Users should have already called close and wait on the returned task
152
+ // before destroying the client. In case they didn't we call close and wait for
153
+ // it to complete. It is safe to call MessageWebSocket::Close multiple times and
154
+ // concurrently, it has safe guards in place to only execute once.
155
+ close ().wait ();
156
+ }
152
157
}
153
158
154
159
pplx::task<void > connect ()
155
160
{
161
+ _ASSERTE (!m_connected);
156
162
const auto &proxy = m_config.proxy ();
157
163
if (!proxy.is_default ())
158
164
{
159
165
return pplx::task_from_exception<void >(websocket_exception (" Only a default proxy server is supported." ));
160
166
}
161
167
162
-
163
-
164
168
const auto &proxy_cred = proxy.credentials ();
165
169
if (proxy_cred.is_set ())
166
170
{
@@ -187,6 +191,7 @@ class winrt_callback_client : public websocket_client_callback_impl, public std:
187
191
websocket_exception exc (e->HResult , build_error_msg (e, " ConnectAsync" ));
188
192
return pplx::task_from_exception<void >(exc);
189
193
}
194
+ m_connected = true ;
190
195
return pplx::task_from_result ();
191
196
});
192
197
}
@@ -410,6 +415,9 @@ class winrt_callback_client : public websocket_client_callback_impl, public std:
410
415
411
416
pplx::task_completion_event<void > m_close_tce;
412
417
418
+ // Tracks whether or not the websocket client successfully connected to the server.
419
+ std::atomic<bool > m_connected;
420
+
413
421
// External callback for handling received and close event
414
422
std::function<void (websocket_incoming_message)> m_external_message_handler;
415
423
std::function<void (websocket_close_status, const utility::string_t &, const std::error_code&)> m_external_close_handler;
0 commit comments