diff --git a/Release/include/cpprest/ws_msg.h b/Release/include/cpprest/ws_msg.h
index 64cee7ae52..73e968a001 100644
--- a/Release/include/cpprest/ws_msg.h
+++ b/Release/include/cpprest/ws_msg.h
@@ -60,10 +60,23 @@ class websocket_outgoing_message
public:
#if !defined(__cplusplus_winrt)
///
- /// Sets a the outgoing message to be an unsolicited pong message.
+ /// Sets the outgoing message to be a ping message.
/// This is useful when the client side wants to check whether the server is alive.
///
- void set_pong_message() { this->set_message_pong(); }
+ /// UTF-8 String containing the optional ping message.
+ void set_ping_message(const std::string& data = {})
+ {
+ this->set_message_ping(concurrency::streams::container_buffer(data));
+ }
+
+ ///
+ /// Sets the outgoing message to be an unsolicited pong message.
+ ///
+ /// UTF-8 String containing the optional pong message.
+ void set_pong_message(const std::string& data = {})
+ {
+ this->set_message_pong(concurrency::streams::container_buffer(data));
+ }
#endif
///
@@ -140,9 +153,14 @@ class websocket_outgoing_message
const pplx::task_completion_event& body_sent() const { return m_body_sent; }
#if !defined(__cplusplus_winrt)
- void set_message_pong()
+ void set_message_ping(const concurrency::streams::container_buffer& buffer)
+ {
+ m_msg_type = websocket_message_type::ping;
+ m_length = static_cast(buffer.size());
+ m_body = buffer;
+ }
+ void set_message_pong(const concurrency::streams::container_buffer& buffer)
{
- concurrency::streams::container_buffer buffer("");
m_msg_type = websocket_message_type::pong;
m_length = static_cast(buffer.size());
m_body = buffer;
diff --git a/Release/src/websockets/client/ws_client_wspp.cpp b/Release/src/websockets/client/ws_client_wspp.cpp
index 326557fee5..5ef74aaf1e 100644
--- a/Release/src/websockets/client/ws_client_wspp.cpp
+++ b/Release/src/websockets/client/ws_client_wspp.cpp
@@ -325,6 +325,35 @@ class wspp_callback_client : public websocket_client_callback_impl,
}
});
+ client.set_ping_handler(
+ [this](websocketpp::connection_hdl, const std::string& msg) {
+ if (m_external_message_handler)
+ {
+ _ASSERTE(m_state >= CONNECTED && m_state < CLOSED);
+ websocket_incoming_message incoming_msg;
+
+ incoming_msg.m_msg_type = websocket_message_type::ping;
+ incoming_msg.m_body = concurrency::streams::container_buffer(msg);
+
+ m_external_message_handler(incoming_msg);
+ }
+ return true;
+ });
+
+ client.set_pong_handler(
+ [this](websocketpp::connection_hdl, const std::string& msg) {
+ if (m_external_message_handler)
+ {
+ _ASSERTE(m_state >= CONNECTED && m_state < CLOSED);
+ websocket_incoming_message incoming_msg;
+
+ incoming_msg.m_msg_type = websocket_message_type::pong;
+ incoming_msg.m_body = concurrency::streams::container_buffer(msg);
+
+ m_external_message_handler(incoming_msg);
+ }
+ });
+
client.set_close_handler([this](websocketpp::connection_hdl con_hdl) {
_ASSERTE(m_state != CLOSED);
shutdown_wspp_impl(con_hdl, false);
@@ -434,12 +463,13 @@ class wspp_callback_client : public websocket_client_callback_impl,
{
case websocket_message_type::text_message:
case websocket_message_type::binary_message:
+ case websocket_message_type::ping:
case websocket_message_type::pong: break;
default: return pplx::task_from_exception(websocket_exception("Message Type not supported."));
}
const auto length = msg.m_length;
- if (length == 0 && msg.m_msg_type != websocket_message_type::pong)
+ if (length == 0 && msg.m_msg_type != websocket_message_type::ping && msg.m_msg_type != websocket_message_type::pong)
{
return pplx::task_from_exception(websocket_exception("Cannot send empty message."));
}
@@ -694,7 +724,18 @@ class wspp_callback_client : public websocket_client_callback_impl,
case websocket_message_type::binary_message:
client.send(this_client->m_con, sp_allocated.get(), length, websocketpp::frame::opcode::binary, ec);
break;
- case websocket_message_type::pong: client.pong(this_client->m_con, "", ec); break;
+ case websocket_message_type::ping:
+ {
+ std::string s(reinterpret_cast(sp_allocated.get()), length);
+ client.ping(this_client->m_con, s, ec);
+ break;
+ }
+ case websocket_message_type::pong:
+ {
+ std::string s(reinterpret_cast(sp_allocated.get()), length);
+ client.pong(this_client->m_con, s, ec);
+ break;
+ }
default:
// This case should have already been filtered above.
std::abort();
diff --git a/Release/tests/functional/websockets/client/send_msg_tests.cpp b/Release/tests/functional/websockets/client/send_msg_tests.cpp
index e99bccd03c..eed1dedf94 100644
--- a/Release/tests/functional/websockets/client/send_msg_tests.cpp
+++ b/Release/tests/functional/websockets/client/send_msg_tests.cpp
@@ -104,16 +104,32 @@ SUITE(send_msg_tests)
}
template
- pplx::task send_pong_msg_helper(SocketClientClass & client, web::uri uri, test_websocket_server & server)
+ pplx::task send_ping_msg_helper(SocketClientClass & client, web::uri uri, test_websocket_server & server,
+ const std::string& body = "")
{
server.next_message(
- [](test_websocket_msg msg) // Handler to verify the message sent by the client.
- { websocket_asserts::assert_message_equals(msg, "", test_websocket_message_type::WEB_SOCKET_PONG_TYPE); });
+ [body](test_websocket_msg msg) // Handler to verify the message sent by the client.
+ { websocket_asserts::assert_message_equals(msg, body, test_websocket_message_type::WEB_SOCKET_PING_TYPE); });
client.connect(uri).wait();
websocket_outgoing_message msg;
- msg.set_pong_message();
+ msg.set_ping_message(body);
+ return client.send(msg);
+ }
+
+ template
+ pplx::task send_pong_msg_helper(SocketClientClass & client, web::uri uri, test_websocket_server & server,
+ const std::string& body = "")
+ {
+ server.next_message(
+ [body](test_websocket_msg msg) // Handler to verify the message sent by the client.
+ { websocket_asserts::assert_message_equals(msg, body, test_websocket_message_type::WEB_SOCKET_PONG_TYPE); });
+
+ client.connect(uri).wait();
+
+ websocket_outgoing_message msg;
+ msg.set_pong_message(body);
return client.send(msg);
}
@@ -493,6 +509,24 @@ SUITE(send_msg_tests)
}
#if !defined(__cplusplus_winrt)
+ // Send a ping message to the server
+ TEST_FIXTURE(uri_address, send_ping_msg)
+ {
+ test_websocket_server server;
+ websocket_client client;
+ send_ping_msg_helper(client, m_uri, server).wait();
+ client.close().wait();
+ }
+
+ // Send a ping message to the server with a body
+ TEST_FIXTURE(uri_address, send_ping_msg_body)
+ {
+ test_websocket_server server;
+ websocket_client client;
+ send_ping_msg_helper(client, m_uri, server, "abcdefghijklmnopqrstuvwxyz").wait();
+ client.close().wait();
+ }
+
// Send an unsolicited pong message to the server
TEST_FIXTURE(uri_address, send_pong_msg)
{
@@ -502,6 +536,15 @@ SUITE(send_msg_tests)
client.close().wait();
}
+ // Send an unsolicited pong message to the server with a body
+ TEST_FIXTURE(uri_address, send_pong_msg_body)
+ {
+ test_websocket_server server;
+ websocket_client client;
+ send_pong_msg_helper(client, m_uri, server, "abcdefghijklmnopqrstuvwxyz").wait();
+ client.close().wait();
+ }
+
// Send an unsolicited pong message to the server with websocket_callback_client
TEST_FIXTURE(uri_address, send_pong_msg_callback_client)
{
diff --git a/Release/tests/functional/websockets/utilities/test_websocket_server.cpp b/Release/tests/functional/websockets/utilities/test_websocket_server.cpp
index 151d03bca0..863376f22a 100644
--- a/Release/tests/functional/websockets/utilities/test_websocket_server.cpp
+++ b/Release/tests/functional/websockets/utilities/test_websocket_server.cpp
@@ -122,6 +122,20 @@ class _test_websocket_server
m_server_connected.set_exception(std::runtime_error("Connection attempt failed."));
});
+ m_srv.set_ping_handler([this](websocketpp::connection_hdl hdl, std::string input) {
+ auto fn = m_test_srv->get_next_message_handler();
+ assert(fn);
+
+ test_websocket_msg wsmsg;
+
+ wsmsg.set_data(std::vector(input.begin(), input.end()));
+
+ wsmsg.set_msg_type(WEB_SOCKET_PING_TYPE);
+ fn(wsmsg);
+
+ return true;
+ });
+
m_srv.set_pong_handler([this](websocketpp::connection_hdl hdl, std::string input) {
auto fn = m_test_srv->get_next_message_handler();
assert(fn);
diff --git a/Release/tests/functional/websockets/utilities/test_websocket_server.h b/Release/tests/functional/websockets/utilities/test_websocket_server.h
index 50489e1a9d..23fbea12e2 100644
--- a/Release/tests/functional/websockets/utilities/test_websocket_server.h
+++ b/Release/tests/functional/websockets/utilities/test_websocket_server.h
@@ -46,6 +46,7 @@ enum test_websocket_message_type
WEB_SOCKET_UTF8_MESSAGE_TYPE,
WEB_SOCKET_UTF8_FRAGMENT_TYPE,
WEB_SOCKET_CLOSE_TYPE,
+ WEB_SOCKET_PING_TYPE,
WEB_SOCKET_PONG_TYPE
};