diff --git a/ixwebsocket/IXWebSocket.cpp b/ixwebsocket/IXWebSocket.cpp index 08563d66..e6759abd 100644 --- a/ixwebsocket/IXWebSocket.cpp +++ b/ixwebsocket/IXWebSocket.cpp @@ -130,7 +130,7 @@ namespace ix std::lock_guard lock(_configMutex); _enablePong = false; } - + void WebSocket::start() { if (_thread.joinable()) return; // we've already been started @@ -188,7 +188,7 @@ namespace ix { std::lock_guard lock(_configMutex); _ws.configure(_perMessageDeflateOptions, - _enablePong, + _enablePong, _pingIntervalSecs, _pingTimeoutSecs); } diff --git a/ixwebsocket/IXWebSocket.h b/ixwebsocket/IXWebSocket.h index 41c15c5d..2b374a31 100644 --- a/ixwebsocket/IXWebSocket.h +++ b/ixwebsocket/IXWebSocket.h @@ -94,7 +94,7 @@ namespace ix void setPingTimeout(int pingTimeoutSecs); void enablePong(); void disablePong(); - + // Run asynchronously, by calling start and stop. void start(); void stop(); diff --git a/ixwebsocket/IXWebSocketTransport.cpp b/ixwebsocket/IXWebSocketTransport.cpp index 1a783ea3..7bb78311 100644 --- a/ixwebsocket/IXWebSocketTransport.cpp +++ b/ixwebsocket/IXWebSocketTransport.cpp @@ -100,7 +100,8 @@ namespace ix void WebSocketTransport::configure(const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions, bool enablePong, - int pingIntervalSecs, int pingTimeoutSecs) + int pingIntervalSecs, + int pingTimeoutSecs) { _perMessageDeflateOptions = perMessageDeflateOptions; _enablePerMessageDeflate = _perMessageDeflateOptions.enabled(); @@ -109,11 +110,18 @@ namespace ix _pingTimeoutSecs = pingTimeoutSecs; if (pingIntervalSecs > 0 && pingTimeoutSecs > 0) - _pingIntervalOrTimeoutGCDSecs = greatestCommonDivisor(pingIntervalSecs, pingTimeoutSecs); + { + _pingIntervalOrTimeoutGCDSecs = greatestCommonDivisor(pingIntervalSecs, + pingTimeoutSecs); + } else if (_pingTimeoutSecs > 0) + { _pingIntervalOrTimeoutGCDSecs = pingTimeoutSecs; + } else + { _pingIntervalOrTimeoutGCDSecs = pingIntervalSecs; + } } // Client @@ -236,13 +244,13 @@ namespace ix if (_readyState == OPEN) { - // if (1) ping timeout is enabled and (2) duration since last received ping response (PONG) - // exceeds the maximum delay, then close the connection + // if (1) ping timeout is enabled and (2) duration since last received + // ping response (PONG) exceeds the maximum delay, then close the connection if (pingTimeoutExceeded()) { close(kInternalErrorCode, kPingTimeoutMessage); } - // If (1) ping is enabled and no ping has been sent for a duration + // If ping is enabled and no ping has been sent for a duration // exceeding our ping interval, send a ping to the server. else if (pingIntervalExceeded()) { @@ -786,10 +794,9 @@ namespace ix WebSocketSendInfo WebSocketTransport::sendPing(const std::string& message) { bool compress = false; - WebSocketSendInfo info = sendData(wsheader_type::PING, message, compress); - if(info.success) + if (info.success) { std::lock_guard lck(_lastSendPingTimePointMutex); _lastSendPingTimePoint = std::chrono::steady_clock::now(); @@ -851,7 +858,7 @@ namespace ix // See list of close events here: // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent - + int codeLength = 2; std::string closure{(char)(code >> 8), (char)(code & 0xff)}; closure.resize(codeLength + reason.size()); diff --git a/ixwebsocket/IXWebSocketTransport.h b/ixwebsocket/IXWebSocketTransport.h index 8f313f51..2dbb0e2e 100644 --- a/ixwebsocket/IXWebSocketTransport.h +++ b/ixwebsocket/IXWebSocketTransport.h @@ -69,7 +69,8 @@ namespace ix void configure(const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions, bool enablePong, - int pingIntervalSecs, int pingTimeoutSecs); + int pingIntervalSecs, + int pingTimeoutSecs); WebSocketInitResult connectToUrl(const std::string& url, // Client int timeoutSecs); @@ -162,24 +163,26 @@ namespace ix // Constants for dealing with closing conneections static const uint16_t kInternalErrorCode; static const uint16_t kAbnormalCloseCode; - const static std::string kInternalErrorMessage; - const static std::string kAbnormalCloseMessage; - const static std::string kPingTimeoutMessage; - + static const std::string kInternalErrorMessage; + static const std::string kAbnormalCloseMessage; + static const std::string kPingTimeoutMessage; + // enable auto response to ping bool _enablePong; static const bool kDefaultEnablePong; // Optional ping and pong timeout + // if both ping interval and timeout are set (> 0), + // then use GCD of these value to wait for the lowest time int _pingIntervalSecs; int _pingTimeoutSecs; - int _pingIntervalOrTimeoutGCDSecs; // if both ping interval and timeout are set (> 0), then use GCD of these value to wait for the lowest time + int _pingIntervalOrTimeoutGCDSecs; static const int kDefaultPingIntervalSecs; static const int kDefaultPingTimeoutSecs; - const static std::string kPingMessage; - - // We record when ping are being sent so that we can know when to send the next one, periodically + static const std::string kPingMessage; + + // We record when ping are being sent so that we can know when to send the next one // We also record when pong are being sent as a reply to pings, to close the connections // if no pong were received sufficiently fast. mutable std::mutex _lastSendPingTimePointMutex; @@ -189,7 +192,7 @@ namespace ix // If this function returns true, it is time to send a new ping bool pingIntervalExceeded(); - + // No PONG data was received through the socket for longer than ping timeout delay bool pingTimeoutExceeded(); diff --git a/test/IXWebSocketPingTest.cpp b/test/IXWebSocketPingTest.cpp index bb1a8285..a9e6f53f 100644 --- a/test/IXWebSocketPingTest.cpp +++ b/test/IXWebSocketPingTest.cpp @@ -211,7 +211,7 @@ TEST_CASE("Websocket_ping_no_data_sent_setHeartBeatPeriod", "[setHeartBeatPeriod webSocketClient.stop(); - // Here we test ping interval + // Here we test ping interval // -> expected ping messages == 1 as 1900 seconds, 1 ping sent every second REQUIRE(serverReceivedPingMessages == 1); @@ -257,7 +257,7 @@ TEST_CASE("Websocket_ping_data_sent_setHeartBeatPeriod", "[setHeartBeatPeriod]") webSocketClient.stop(); - // Here we test ping interval + // Here we test ping interval // client has sent data, but ping should have been sent no matter what // -> expected ping messages == 2 as 900+900+1100 = 2900 seconds, 1 ping sent every second REQUIRE(serverReceivedPingMessages == 2); @@ -301,7 +301,7 @@ TEST_CASE("Websocket_ping_no_data_sent_setPingInterval", "[setPingInterval]") webSocketClient.stop(); - // Here we test ping interval + // Here we test ping interval // -> expected ping messages == 2 as 2100 seconds, 1 ping sent every second REQUIRE(serverReceivedPingMessages == 2); @@ -347,7 +347,7 @@ TEST_CASE("Websocket_ping_data_sent_setPingInterval", "[setPingInterval]") webSocketClient.stop(); - // Here we test ping interval + // Here we test ping interval // client has sent data, but ping should have been sent no matter what // -> expected ping messages == 3 as 900+900+1300 = 3100 seconds, 1 ping sent every second REQUIRE(serverReceivedPingMessages == 3); diff --git a/test/IXWebSocketPingTimeoutTest.cpp b/test/IXWebSocketPingTimeoutTest.cpp index 74b523ff..4477b241 100644 --- a/test/IXWebSocketPingTimeoutTest.cpp +++ b/test/IXWebSocketPingTimeoutTest.cpp @@ -113,7 +113,7 @@ namespace } _webSocket.disableAutomaticReconnection(); - + } else if (messageType == ix::WebSocket_MessageType_Error) { @@ -229,7 +229,7 @@ TEST_CASE("Websocket_ping_timeout_not_checked", "[setPingTimeout]") ix::setupWebSocketTrafficTrackerCallback(); int port = getFreePort(); - ix::WebSocketServer server(port); + ix::WebSocketServer server(port); std::atomic serverReceivedPingMessages(0); bool enablePong = false; // Pong is disabled on Server REQUIRE(startServer(server, serverReceivedPingMessages, enablePong)); @@ -282,7 +282,7 @@ TEST_CASE("Websocket_ping_no_timeout", "[setPingTimeout]") ix::setupWebSocketTrafficTrackerCallback(); int port = getFreePort(); - ix::WebSocketServer server(port); + ix::WebSocketServer server(port); std::atomic serverReceivedPingMessages(0); bool enablePong = true; // Pong is enabled on Server REQUIRE(startServer(server, serverReceivedPingMessages, enablePong)); @@ -335,7 +335,7 @@ TEST_CASE("Websocket_no_ping_but_timeout", "[setPingTimeout]") ix::setupWebSocketTrafficTrackerCallback(); int port = getFreePort(); - ix::WebSocketServer server(port); + ix::WebSocketServer server(port); std::atomic serverReceivedPingMessages(0); bool enablePong = false; // Pong is disabled on Server REQUIRE(startServer(server, serverReceivedPingMessages, enablePong)); @@ -388,7 +388,7 @@ TEST_CASE("Websocket_ping_timeout", "[setPingTimeout]") ix::setupWebSocketTrafficTrackerCallback(); int port = getFreePort(); - ix::WebSocketServer server(port); + ix::WebSocketServer server(port); std::atomic serverReceivedPingMessages(0); bool enablePong = false; // Pong is disabled on Server REQUIRE(startServer(server, serverReceivedPingMessages, enablePong)); @@ -439,7 +439,7 @@ TEST_CASE("Websocket_ping_long_timeout", "[setPingTimeout]") ix::setupWebSocketTrafficTrackerCallback(); int port = getFreePort(); - ix::WebSocketServer server(port); + ix::WebSocketServer server(port); std::atomic serverReceivedPingMessages(0); bool enablePong = false; // Pong is disabled on Server REQUIRE(startServer(server, serverReceivedPingMessages, enablePong));