Skip to content

Commit 907b6e6

Browse files
committed
Merge branch 'glukacsy-pongsupport' into development
2 parents 3c41279 + 32d4a4c commit 907b6e6

File tree

5 files changed

+83
-6
lines changed

5 files changed

+83
-6
lines changed

Release/include/cpprest/ws_msg.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,17 @@ class websocket_outgoing_message
7373
{
7474
public:
7575

76+
#if !defined(__cplusplus_winrt)
77+
/// <summary>
78+
/// Sets a the outgoing message to be an unsolicited pong message.
79+
/// This is useful when the client side wants to check whether the server is alive.
80+
/// </summary>
81+
void set_pong_message()
82+
{
83+
this->set_message_pong();
84+
}
85+
#endif
86+
7687
/// <summary>
7788
/// Sets a UTF-8 message as the message body.
7889
/// </summary>
@@ -152,6 +163,16 @@ class websocket_outgoing_message
152163

153164
const pplx::task_completion_event<void> & body_sent() const { return m_body_sent; }
154165

166+
#if !defined(__cplusplus_winrt)
167+
void set_message_pong()
168+
{
169+
concurrency::streams::container_buffer<std::string> buffer("");
170+
m_msg_type = websocket_message_type::pong;
171+
m_length = static_cast<size_t>(buffer.size());
172+
m_body = buffer;
173+
}
174+
#endif
175+
155176
void set_message(const concurrency::streams::container_buffer<std::string> &buffer)
156177
{
157178
m_msg_type = websocket_message_type::text_message;

Release/src/websockets/client/ws_client_wspp.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,13 +373,14 @@ class wspp_callback_client : public websocket_client_callback_impl, public std::
373373
{
374374
case websocket_message_type::text_message:
375375
case websocket_message_type::binary_message:
376+
case websocket_message_type::pong:
376377
break;
377378
default:
378379
return pplx::task_from_exception<void>(websocket_exception("Invalid message type"));
379380
}
380381

381382
const auto length = msg.m_length;
382-
if (length == 0)
383+
if (length == 0 && msg.m_msg_type != websocket_message_type::pong)
383384
{
384385
return pplx::task_from_exception<void>(websocket_exception("Cannot send empty message."));
385386
}
@@ -639,13 +640,19 @@ class wspp_callback_client : public websocket_client_callback_impl, public std::
639640
ec);
640641
break;
641642
case websocket_message_type::binary_message:
642-
client.send(
643+
client.send(
643644
this_client->m_con,
644645
sp_allocated.get(),
645646
length,
646647
websocketpp::frame::opcode::binary,
647648
ec);
648649
break;
650+
case websocket_message_type::pong:
651+
client.pong(
652+
this_client->m_con,
653+
"",
654+
ec);
655+
break;
649656
default:
650657
// This case should have already been filtered above.
651658
std::abort();

Release/tests/functional/websockets/client/send_msg_tests.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,21 @@ pplx::task<void> send_text_msg_helper(SocketClientClass& client, web::uri uri, t
103103
return client.send(msg);
104104
}
105105

106+
template<class SocketClientClass>
107+
pplx::task<void> send_pong_msg_helper(SocketClientClass& client, web::uri uri, test_websocket_server& server)
108+
{
109+
server.next_message([](test_websocket_msg msg) // Handler to verify the message sent by the client.
110+
{
111+
websocket_asserts::assert_message_equals(msg, "", test_websocket_message_type::WEB_SOCKET_PONG_TYPE);
112+
});
113+
114+
client.connect(uri).wait();
115+
116+
websocket_outgoing_message msg;
117+
msg.set_pong_message();
118+
return client.send(msg);
119+
}
120+
106121
pplx::task<void> send_msg_from_stream(websocket_client& client,
107122
test_websocket_server& server,
108123
web::uri uri,
@@ -456,6 +471,26 @@ TEST_FIXTURE(uri_address, send_stream_binary_msg_no_length)
456471
client.close().wait();
457472
}
458473

474+
#if !defined(__cplusplus_winrt)
475+
// Send an unsolicited pong message to the server
476+
TEST_FIXTURE(uri_address, send_pong_msg)
477+
{
478+
test_websocket_server server;
479+
websocket_client client;
480+
send_pong_msg_helper(client, m_uri, server).wait();
481+
client.close().wait();
482+
}
483+
484+
// Send an unsolicited pong message to the server with websocket_callback_client
485+
TEST_FIXTURE(uri_address, send_pong_msg_callback_client)
486+
{
487+
test_websocket_server server;
488+
websocket_callback_client client;
489+
send_pong_msg_helper(client, m_uri, server).wait();
490+
client.close().wait();
491+
}
492+
#endif
493+
459494
} // SUITE(send_msg_tests)
460495

461496
}}}}

Release/tests/functional/websockets/utilities/test_websocket_server.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ namespace utilities {
134134
m_server_connected.set_exception(std::runtime_error("Connection attempt failed."));
135135
});
136136

137+
m_srv.set_pong_handler([this](websocketpp::connection_hdl hdl, std::string input)
138+
{
139+
auto fn = m_test_srv->get_next_message_handler();
140+
assert(fn);
141+
142+
test_websocket_msg wsmsg;
143+
144+
wsmsg.set_data(std::vector<uint8_t>(input.begin(), input.end()));
145+
146+
wsmsg.set_msg_type(WEB_SOCKET_PONG_TYPE);
147+
fn(wsmsg);
148+
});
149+
137150
m_srv.set_message_handler([this](websocketpp::connection_hdl hdl, server::message_ptr msg)
138151
{
139152
auto pay = msg->get_payload();
@@ -151,12 +164,12 @@ namespace utilities {
151164
wsmsg.set_msg_type(utilities::WEB_SOCKET_BINARY_MESSAGE_TYPE);
152165
break;
153166
case websocketpp::frame::opcode::text:
154-
wsmsg.set_msg_type(utilities::WEB_SOCKET_UTF8_MESSAGE_TYPE);
167+
wsmsg.set_msg_type(utilities::WEB_SOCKET_UTF8_MESSAGE_TYPE);
155168
break;
156169
case websocketpp::frame::opcode::close:
157170
wsmsg.set_msg_type(utilities::WEB_SOCKET_CLOSE_TYPE);
158171
break;
159-
default:
172+
default:
160173
// Websocketspp does not currently support explicit fragmentation. We should not get here.
161174
std::abort();
162175
}
@@ -262,7 +275,7 @@ namespace utilities {
262275
case test_websocket_message_type::WEB_SOCKET_CLOSE_TYPE:
263276
flags = websocketpp::frame::opcode::close; // WebSocket::FRAME_OP_CLOSE;
264277
break;
265-
case test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE:
278+
case test_websocket_message_type::WEB_SOCKET_UTF8_FRAGMENT_TYPE:
266279
case test_websocket_message_type::WEB_SOCKET_BINARY_FRAGMENT_TYPE:
267280
default:
268281
throw std::runtime_error("invalid message type");

Release/tests/functional/websockets/utilities/test_websocket_server.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ enum test_websocket_message_type
5050
WEB_SOCKET_BINARY_FRAGMENT_TYPE,
5151
WEB_SOCKET_UTF8_MESSAGE_TYPE,
5252
WEB_SOCKET_UTF8_FRAGMENT_TYPE,
53-
WEB_SOCKET_CLOSE_TYPE
53+
WEB_SOCKET_CLOSE_TYPE,
54+
WEB_SOCKET_PONG_TYPE
5455
};
5556

5657
// Interface containing details about the HTTP handshake request received by the test server.

0 commit comments

Comments
 (0)