Skip to content

Commit 3d16311

Browse files
committed
Fixing issue with reporting connection aborted with winrt websocket_client.
Conflicts: Release/src/websockets/client/ws_winrt.cpp
1 parent 6ff179c commit 3d16311

File tree

1 file changed

+31
-22
lines changed

1 file changed

+31
-22
lines changed

Release/src/websockets/client/ws_winrt.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,17 @@ namespace client
4646
namespace details
4747
{
4848

49+
// Helper function to build an error string from a Platform::Exception and a location.
50+
static std::string build_error_msg(Platform::Exception ^exc, const std::string &location)
51+
{
52+
std::string msg(location);
53+
msg.append(": ");
54+
msg.append(std::to_string(exc->HResult));
55+
msg.append(": ");
56+
msg.append(utility::conversions::utf16_to_utf8(exc->Message->Data()));
57+
return msg;
58+
}
59+
4960
// This class is required by the implementation in order to function:
5061
// The TypedEventHandler requires the message received and close handler to be a member of WinRT class.
5162
ref class ReceiveContext sealed
@@ -59,13 +70,16 @@ ref class ReceiveContext sealed
5970

6071
private:
6172
// Public members cannot have native types
62-
ReceiveContext(std::function<void(websocket_incoming_message &)> receive_handler, std::function<void()> close_handler): m_receive_handler(receive_handler), m_close_handler(close_handler) {}
73+
ReceiveContext(
74+
std::function<void(websocket_incoming_message &)> receive_handler,
75+
std::function<void(const websocket_exception &)> close_handler)
76+
: m_receive_handler(std::move(receive_handler)), m_close_handler(std::move(close_handler)) {}
6377

6478
// Handler to be executed when a message has been received by the client
6579
std::function<void(websocket_incoming_message &)> m_receive_handler;
6680

6781
// Handler to be executed when a close message has been received by the client
68-
std::function<void()> m_close_handler;
82+
std::function<void(const websocket_exception &)> m_close_handler;
6983
};
7084

7185
class winrt_client : public _websocket_client_impl, public std::enable_shared_from_this<winrt_client>
@@ -128,9 +142,9 @@ class winrt_client : public _websocket_client_impl, public std::enable_shared_fr
128142
// Setting the tce outside the receive lock for better performance
129143
tce.set(msg);
130144
},
131-
[=]() // Close handler called upon receiving a close frame from the server.
145+
[=](const websocket_exception &e)
132146
{
133-
close_pending_tasks_with_error();
147+
close_pending_tasks_with_error(e);
134148
m_close_tce.set();
135149
m_server_close_complete.set();
136150
});
@@ -150,19 +164,19 @@ class winrt_client : public _websocket_client_impl, public std::enable_shared_fr
150164
}
151165
else
152166
{
153-
close_pending_tasks_with_error();
167+
close_pending_tasks_with_error(websocket_exception("websocket_client is being destroyed"));
154168
}
155169
}
156170

157-
void close_pending_tasks_with_error()
171+
void close_pending_tasks_with_error(const websocket_exception &exc)
158172
{
159173
std::lock_guard<std::mutex> lock(m_receive_queue_lock);
160174
m_client_closed = true;
161175
while(!m_receive_task_queue.empty()) // There are tasks waiting to receive a message, signal them
162176
{
163177
auto tce = m_receive_task_queue.front();
164178
m_receive_task_queue.pop();
165-
tce.set_exception(std::make_exception_ptr(websocket_exception("Websocket connection has been closed.")));
179+
tce.set_exception(std::make_exception_ptr(exc));
166180
}
167181
}
168182

@@ -195,10 +209,11 @@ class winrt_client : public _websocket_client_impl, public std::enable_shared_fr
195209
result.get();
196210
m_messageWriter = ref new DataWriter(m_msg_websocket->OutputStream);
197211
}
198-
catch(Platform::Exception^ ex)
212+
catch(Platform::Exception^ e)
199213
{
200-
close_pending_tasks_with_error();
201-
return pplx::task_from_exception<void>(websocket_exception(ex->HResult));
214+
websocket_exception exc(e->HResult, build_error_msg(e, "ConnectAsync"));
215+
close_pending_tasks_with_error(exc);
216+
return pplx::task_from_exception<void>(exc);
202217
}
203218
return pplx::task_from_result();
204219
});
@@ -436,10 +451,8 @@ class winrt_client : public _websocket_client_impl, public std::enable_shared_fr
436451
// completed. The websocket_client destructor can wait on this event before proceeding.
437452
Concurrency::event m_server_close_complete;
438453

439-
// m_client_closed maintains the state of the client. It is set to true when:
440-
// 1. the client has not connected
441-
// 2. if it has received a close frame from the server.
442-
// We may want to keep an enum to maintain the client state in the future.
454+
// Initially set to false, becomes true if a close frame is received from the server or
455+
// if the underlying connection is aborted or terminated.
443456
bool m_client_closed;
444457

445458
// When a message arrives, if there are tasks waiting for a message, signal the topmost one.
@@ -490,19 +503,15 @@ void ReceiveContext::OnReceive(MessageWebSocket^ sender, MessageWebSocketMessage
490503
msg->set_length(len);
491504
m_receive_handler(ws_incoming_message);
492505
}
493-
catch(...)
506+
catch (Platform::Exception ^e)
494507
{
495-
// Swallow the exception for now. Following up on this with the WinRT team.
496-
// We can handle this more gracefully once we know the scenarios where DataReader operations can throw an exception:
497-
// When socket gets into a bad state
498-
// or only when we receive a valid message and message processing fails.
499-
// Tracking this on codeplex with : https://casablanca.codeplex.com/workitem/181
508+
m_close_handler(websocket_exception(e->HResult, build_error_msg(e, "OnReceive")));
500509
}
501510
}
502511

503512
void ReceiveContext::OnClosed(IWebSocket^ sender, WebSocketClosedEventArgs^ args)
504513
{
505-
m_close_handler();
514+
m_close_handler(websocket_exception("close frame received from server"));
506515
}
507516
}
508517

@@ -515,4 +524,4 @@ websocket_client::websocket_client(websocket_client_config config) :
515524
{}
516525

517526
}}}
518-
#endif /* WINAPI_FAMILY == WINAPI_FAMILY_APP */
527+
#endif

0 commit comments

Comments
 (0)