mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-06 03:31:43 +00:00
[wpinet] WebSocket: Send pong in response to ping (#5498)
This is required by the spec (RFC 6455 section 5.5.2).
This commit is contained in:
@@ -573,6 +573,19 @@ void WebSocket::HandleIncoming(uv::Buffer& buf, size_t size) {
|
|||||||
if (!fin) {
|
if (!fin) {
|
||||||
return Fail(1002, "cannot fragment control frames");
|
return Fail(1002, "cannot fragment control frames");
|
||||||
}
|
}
|
||||||
|
// If the connection is open, send a Pong in response
|
||||||
|
if (m_state == OPEN) {
|
||||||
|
SmallVector<uv::Buffer, 4> bufs;
|
||||||
|
{
|
||||||
|
raw_uv_ostream os{bufs, 4096};
|
||||||
|
os << m_payload;
|
||||||
|
}
|
||||||
|
SendPong(bufs, [](auto bufs, uv::Error) {
|
||||||
|
for (auto&& buf : bufs) {
|
||||||
|
buf.Deallocate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
ping(m_payload);
|
ping(m_payload);
|
||||||
break;
|
break;
|
||||||
case kOpPong:
|
case kOpPong:
|
||||||
|
|||||||
@@ -460,7 +460,8 @@ class WebSocket : public std::enable_shared_from_this<WebSocket> {
|
|||||||
sig::Signal<std::span<const uint8_t>, bool> binary;
|
sig::Signal<std::span<const uint8_t>, bool> binary;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ping event. Emitted when a ping message is received.
|
* Ping event. Emitted when a ping message is received. A pong message is
|
||||||
|
* automatically sent in response, so this is simply a notification.
|
||||||
*/
|
*/
|
||||||
sig::Signal<std::span<const uint8_t>> ping;
|
sig::Signal<std::span<const uint8_t>> ping;
|
||||||
|
|
||||||
|
|||||||
@@ -147,4 +147,45 @@ TEST_F(WebSocketIntegrationTest, ClientSendText) {
|
|||||||
ASSERT_EQ(gotData, 1);
|
ASSERT_EQ(gotData, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(WebSocketIntegrationTest, ServerSendPing) {
|
||||||
|
int gotPing = 0;
|
||||||
|
int gotPong = 0;
|
||||||
|
|
||||||
|
serverPipe->Listen([&]() {
|
||||||
|
auto conn = serverPipe->Accept();
|
||||||
|
auto server = WebSocketServer::Create(*conn);
|
||||||
|
server->connected.connect([&](std::string_view, WebSocket& ws) {
|
||||||
|
ws.SendPing({uv::Buffer{"\x03\x04", 2}}, [&](auto, uv::Error) {});
|
||||||
|
ws.pong.connect([&](auto data) {
|
||||||
|
++gotPong;
|
||||||
|
std::vector<uint8_t> recvData{data.begin(), data.end()};
|
||||||
|
std::vector<uint8_t> expectData{0x03, 0x04};
|
||||||
|
ASSERT_EQ(recvData, expectData);
|
||||||
|
ws.Close();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
clientPipe->Connect(pipeName, [&] {
|
||||||
|
auto ws = WebSocket::CreateClient(*clientPipe, "/test", pipeName);
|
||||||
|
ws->closed.connect([&](uint16_t code, std::string_view reason) {
|
||||||
|
Finish();
|
||||||
|
if (code != 1005 && code != 1006) {
|
||||||
|
FAIL() << "Code: " << code << " Reason: " << reason;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ws->ping.connect([&](auto data) {
|
||||||
|
++gotPing;
|
||||||
|
std::vector<uint8_t> recvData{data.begin(), data.end()};
|
||||||
|
std::vector<uint8_t> expectData{0x03, 0x04};
|
||||||
|
ASSERT_EQ(recvData, expectData);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
loop->Run();
|
||||||
|
|
||||||
|
ASSERT_EQ(gotPing, 1);
|
||||||
|
ASSERT_EQ(gotPong, 1);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace wpi
|
} // namespace wpi
|
||||||
|
|||||||
Reference in New Issue
Block a user