#pragma once #include "providers/liveupdates/BasicPubSubClient.hpp" #include "providers/twitch/pubsubmessages/Message.hpp" #include #include #include #include namespace chatterino { struct TopicData { QString topic; bool operator==(const TopicData &other) const { return this->topic == other.topic; } friend QDebug operator<<(QDebug debug, const TopicData &data); }; } // namespace chatterino template <> struct std::hash { std::size_t operator()(const chatterino::TopicData &data) const noexcept { return std::hash{}(data.topic); } }; namespace chatterino { struct PubSubMessage; class PubSub; struct PubSubListenMessage; class PubSubClient : public BasicPubSubClient { public: // The max amount of topics we may listen to with a single connection static constexpr size_t MAX_LISTENS = 50; struct UnlistenPrefixResponse { std::vector topics; QString nonce; }; PubSubClient(PubSub &manager, std::chrono::milliseconds heartbeatInterval); void onOpen() /* override */; void onMessage(const QByteArray &msg) /* override */; void checkHeartbeat(); QByteArray encodeSubscription( const Subscription &subscription) /* override */; QByteArray encodeUnsubscription( const Subscription &subscription) /* override */; private: struct NonceInfo { bool isListen; }; void handleResponse(const PubSubMessage &message); void handleMessageResponse(const PubSubMessageMessage &message); std::unordered_map nonces_; std::atomic> lastHeartbeat_; std::chrono::milliseconds heartbeatInterval_; bool isOpen_ = false; PubSub &manager_; }; } // namespace chatterino