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