Added support for setting custom ping messages with support for any 'ping' message type (binary ping message, text ping message) (#438)
* Added support for setting custom ping messages with support for any 'ping' message type (binary ping message, text ping message) * Add default value --------- Co-authored-by: YuHuanTin <2@>
This commit is contained in:
		| @@ -39,6 +39,7 @@ namespace ix | ||||
|         , _handshakeTimeoutSecs(kDefaultHandShakeTimeoutSecs) | ||||
|         , _enablePong(kDefaultEnablePong) | ||||
|         , _pingIntervalSecs(kDefaultPingIntervalSecs) | ||||
|         , _pingType(SendMessageKind::Ping) | ||||
|     { | ||||
|         _ws.setOnCloseCallback( | ||||
|             [this](uint16_t code, const std::string& reason, size_t wireSize, bool remote) | ||||
| @@ -101,6 +102,17 @@ namespace ix | ||||
|         return _perMessageDeflateOptions; | ||||
|     } | ||||
|  | ||||
|     void WebSocket::setPingMessage(const std::string& sendMessage, SendMessageKind pingType) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_configMutex); | ||||
|         _pingMessage = sendMessage; | ||||
|         _ws.setPingMessage(_pingMessage, pingType); | ||||
|     } | ||||
|     const std::string WebSocket::getPingMessage() const | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_configMutex); | ||||
|         return _pingMessage; | ||||
|     } | ||||
|     void WebSocket::setPingInterval(int pingIntervalSecs) | ||||
|     { | ||||
|         std::lock_guard<std::mutex> lock(_configMutex); | ||||
| @@ -233,7 +245,7 @@ namespace ix | ||||
|         if (_pingIntervalSecs > 0) | ||||
|         { | ||||
|             // Send a heart beat right away | ||||
|             _ws.sendHeartBeat(); | ||||
|             _ws.sendHeartBeat(_pingType); | ||||
|         } | ||||
|  | ||||
|         return status; | ||||
| @@ -268,7 +280,7 @@ namespace ix | ||||
|         if (_pingIntervalSecs > 0) | ||||
|         { | ||||
|             // Send a heart beat right away | ||||
|             _ws.sendHeartBeat(); | ||||
|             _ws.sendHeartBeat(_pingType); | ||||
|         } | ||||
|  | ||||
|         return status; | ||||
| @@ -506,13 +518,13 @@ namespace ix | ||||
|         return sendMessage(text, SendMessageKind::Text, onProgressCallback); | ||||
|     } | ||||
|  | ||||
|     WebSocketSendInfo WebSocket::ping(const std::string& text) | ||||
|     WebSocketSendInfo WebSocket::ping(const std::string& text, SendMessageKind pingType) | ||||
|     { | ||||
|         // Standard limit ping message size | ||||
|         constexpr size_t pingMaxPayloadSize = 125; | ||||
|         if (text.size() > pingMaxPayloadSize) return WebSocketSendInfo(false); | ||||
|  | ||||
|         return sendMessage(text, SendMessageKind::Ping); | ||||
|         return sendMessage(text, pingType); | ||||
|     } | ||||
|  | ||||
|     WebSocketSendInfo WebSocket::sendMessage(const IXWebSocketSendData& message, | ||||
|   | ||||
| @@ -53,6 +53,8 @@ namespace ix | ||||
|         void setPerMessageDeflateOptions( | ||||
|             const WebSocketPerMessageDeflateOptions& perMessageDeflateOptions); | ||||
|         void setTLSOptions(const SocketTLSOptions& socketTLSOptions); | ||||
|         void setPingMessage(const std::string& sendMessage, | ||||
|                             SendMessageKind pingType = SendMessageKind::Ping); | ||||
|         void setPingInterval(int pingIntervalSecs); | ||||
|         void enablePong(); | ||||
|         void disablePong(); | ||||
| @@ -88,7 +90,7 @@ namespace ix | ||||
|                                        const OnProgressCallback& onProgressCallback = nullptr); | ||||
|         WebSocketSendInfo sendText(const std::string& text, | ||||
|                                    const OnProgressCallback& onProgressCallback = nullptr); | ||||
|         WebSocketSendInfo ping(const std::string& text); | ||||
|         WebSocketSendInfo ping(const std::string& text,SendMessageKind pingType = SendMessageKind::Ping); | ||||
|  | ||||
|         void close(uint16_t code = WebSocketCloseConstants::kNormalClosureCode, | ||||
|                    const std::string& reason = WebSocketCloseConstants::kNormalClosureMessage); | ||||
| @@ -103,6 +105,7 @@ namespace ix | ||||
|  | ||||
|         const std::string getUrl() const; | ||||
|         const WebSocketPerMessageDeflateOptions getPerMessageDeflateOptions() const; | ||||
|         const std::string getPingMessage() const; | ||||
|         int getPingInterval() const; | ||||
|         size_t bufferedAmount() const; | ||||
|  | ||||
| @@ -170,6 +173,8 @@ namespace ix | ||||
|         // Optional ping and pong timeout | ||||
|         int _pingIntervalSecs; | ||||
|         int _pingTimeoutSecs; | ||||
|         std::string _pingMessage; | ||||
|         SendMessageKind _pingType; | ||||
|         static const int kDefaultPingIntervalSecs; | ||||
|         static const int kDefaultPingTimeoutSecs; | ||||
|  | ||||
|   | ||||
| @@ -54,7 +54,6 @@ | ||||
|  | ||||
| namespace ix | ||||
| { | ||||
|     const std::string WebSocketTransport::kPingMessage("ixwebsocket::heartbeat"); | ||||
|     const int WebSocketTransport::kDefaultPingIntervalSecs(-1); | ||||
|     const bool WebSocketTransport::kDefaultEnablePong(true); | ||||
|     const int WebSocketTransport::kClosingMaximumWaitingDelayInMs(300); | ||||
| @@ -73,6 +72,9 @@ namespace ix | ||||
|         , _closingTimePoint(std::chrono::steady_clock::now()) | ||||
|         , _enablePong(kDefaultEnablePong) | ||||
|         , _pingIntervalSecs(kDefaultPingIntervalSecs) | ||||
|         , _setCustomMessage(false) | ||||
|         , _kPingMessage("ixwebsocket::heartbeat") | ||||
|         , _pingType(SendMessageKind::Ping) | ||||
|         , _pongReceived(false) | ||||
|         , _pingCount(0) | ||||
|         , _lastSendPingTimePoint(std::chrono::steady_clock::now()) | ||||
| @@ -250,13 +252,51 @@ namespace ix | ||||
|         return now - _lastSendPingTimePoint > std::chrono::seconds(_pingIntervalSecs); | ||||
|     } | ||||
|  | ||||
|     WebSocketSendInfo WebSocketTransport::sendHeartBeat() | ||||
|     void WebSocketTransport::setPingMessage(const std::string& message, SendMessageKind pingType) | ||||
|     { | ||||
|         _setCustomMessage = true; | ||||
|         _kPingMessage = message; | ||||
|         _pingType = pingType; | ||||
|     } | ||||
|  | ||||
|     WebSocketSendInfo WebSocketTransport::sendHeartBeat(SendMessageKind pingMessage) | ||||
|     { | ||||
|         _pongReceived = false; | ||||
|         std::stringstream ss; | ||||
|         ss << kPingMessage << "::" << _pingIntervalSecs << "s" | ||||
|            << "::" << _pingCount++; | ||||
|         return sendPing(ss.str()); | ||||
|  | ||||
|         ss << _kPingMessage; | ||||
|         if (!_setCustomMessage) | ||||
|         { | ||||
|             ss << "::" << _pingIntervalSecs << "s" | ||||
|                << "::" << _pingCount++; | ||||
|         } | ||||
|         if (pingMessage == SendMessageKind::Ping) | ||||
|         { | ||||
|             return sendPing(ss.str()); | ||||
|         } | ||||
|         else if (pingMessage == SendMessageKind::Binary) | ||||
|         { | ||||
|             WebSocketSendInfo info = sendBinary(ss.str(), nullptr); | ||||
|             if (info.success) | ||||
|             { | ||||
|                 std::lock_guard<std::mutex> lck(_lastSendPingTimePointMutex); | ||||
|                 _lastSendPingTimePoint = std::chrono::steady_clock::now(); | ||||
|             } | ||||
|             return info; | ||||
|         } | ||||
|         else if (pingMessage == SendMessageKind::Text) | ||||
|         { | ||||
|             WebSocketSendInfo info = sendText(ss.str(), nullptr); | ||||
|             if (info.success) | ||||
|             { | ||||
|                 std::lock_guard<std::mutex> lck(_lastSendPingTimePointMutex); | ||||
|                 _lastSendPingTimePoint = std::chrono::steady_clock::now(); | ||||
|             } | ||||
|             return info; | ||||
|         } | ||||
|  | ||||
|         // unknow type ping message | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     bool WebSocketTransport::closingDelayExceeded() | ||||
| @@ -272,7 +312,9 @@ namespace ix | ||||
|         { | ||||
|             if (pingIntervalExceeded()) | ||||
|             { | ||||
|                 if (!_pongReceived) | ||||
|                 // If it is not a 'ping' message of ping type, there is no need to judge whether | ||||
|                 // pong will receive it | ||||
|                 if (_pingType == SendMessageKind::Ping && !_pongReceived) | ||||
|                 { | ||||
|                     // ping response (PONG) exceeds the maximum delay, close the connection | ||||
|                     close(WebSocketCloseConstants::kInternalErrorCode, | ||||
| @@ -280,7 +322,7 @@ namespace ix | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     sendHeartBeat(); | ||||
|                     sendHeartBeat(_pingType); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|   | ||||
| @@ -109,8 +109,12 @@ namespace ix | ||||
|         void dispatch(PollResult pollResult, const OnMessageCallback& onMessageCallback); | ||||
|         size_t bufferedAmount() const; | ||||
|  | ||||
|         // set ping heartbeat message | ||||
|         void setPingMessage(const std::string& message, SendMessageKind pingType); | ||||
|  | ||||
|         // internal | ||||
|         WebSocketSendInfo sendHeartBeat(); | ||||
|         // send any type of ping packet, not only 'ping' type | ||||
|         WebSocketSendInfo sendHeartBeat(SendMessageKind pingType); | ||||
|  | ||||
|     private: | ||||
|         std::string _url; | ||||
| @@ -215,7 +219,10 @@ namespace ix | ||||
|         std::atomic<bool> _pongReceived; | ||||
|  | ||||
|         static const int kDefaultPingIntervalSecs; | ||||
|         static const std::string kPingMessage; | ||||
|  | ||||
|         bool _setCustomMessage; | ||||
|         std::string _kPingMessage; | ||||
|         SendMessageKind _pingType; | ||||
|         std::atomic<uint64_t> _pingCount; | ||||
|  | ||||
|         // We record when ping are being sent so that we can know when to send the next one | ||||
|   | ||||
		Reference in New Issue
	
	Block a user