1
0

test_websocket_heartbeat.cc 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // Standalone test for WebSocket automatic heartbeat.
  2. // Compiled with a 1-second ping interval so we can verify heartbeat behavior
  3. // without waiting 30 seconds.
  4. #define CPPHTTPLIB_WEBSOCKET_PING_INTERVAL_SECOND 1
  5. #define CPPHTTPLIB_WEBSOCKET_READ_TIMEOUT_SECOND 3
  6. #include <httplib.h>
  7. #include "gtest/gtest.h"
  8. using namespace httplib;
  9. class WebSocketHeartbeatTest : public ::testing::Test {
  10. protected:
  11. void SetUp() override {
  12. svr_.WebSocket("/ws", [](const Request &, ws::WebSocket &ws) {
  13. std::string msg;
  14. while (ws.read(msg)) {
  15. ws.send(msg);
  16. }
  17. });
  18. port_ = svr_.bind_to_any_port("localhost");
  19. thread_ = std::thread([this]() { svr_.listen_after_bind(); });
  20. svr_.wait_until_ready();
  21. }
  22. void TearDown() override {
  23. svr_.stop();
  24. thread_.join();
  25. }
  26. Server svr_;
  27. int port_;
  28. std::thread thread_;
  29. };
  30. // Verify that an idle connection stays alive beyond the read timeout
  31. // thanks to automatic heartbeat pings.
  32. TEST_F(WebSocketHeartbeatTest, IdleConnectionStaysAlive) {
  33. ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) + "/ws");
  34. ASSERT_TRUE(client.connect());
  35. // Sleep longer than read timeout (3s). Without heartbeat, the connection
  36. // would time out. With heartbeat pings every 1s, it stays alive.
  37. std::this_thread::sleep_for(std::chrono::seconds(5));
  38. // Connection should still be open
  39. ASSERT_TRUE(client.is_open());
  40. // Verify we can still exchange messages
  41. ASSERT_TRUE(client.send("hello after idle"));
  42. std::string msg;
  43. ASSERT_TRUE(client.read(msg));
  44. EXPECT_EQ("hello after idle", msg);
  45. client.close();
  46. }
  47. // Verify that multiple heartbeat cycles work
  48. TEST_F(WebSocketHeartbeatTest, MultipleHeartbeatCycles) {
  49. ws::WebSocketClient client("ws://localhost:" + std::to_string(port_) + "/ws");
  50. ASSERT_TRUE(client.connect());
  51. // Wait through several heartbeat cycles
  52. for (int i = 0; i < 3; i++) {
  53. std::this_thread::sleep_for(std::chrono::milliseconds(1500));
  54. ASSERT_TRUE(client.is_open());
  55. std::string text = "msg" + std::to_string(i);
  56. ASSERT_TRUE(client.send(text));
  57. std::string msg;
  58. ASSERT_TRUE(client.read(msg));
  59. EXPECT_EQ(text, msg);
  60. }
  61. client.close();
  62. }