Twitch SDK (Internal)
pubsubclient.h
Go to the documentation of this file.
1 /********************************************************************************************
2 * Twitch Broadcasting SDK
3 *
4 * This software is supplied under the terms of a license agreement with Twitch Interactive, Inc. and
5 * may not be copied or used except in accordance with the terms of that agreement
6 * Copyright (c) 2012-2016 Twitch Interactive, Inc.
7 *********************************************************************************************/
8 
9 #pragma once
10 
16 #include "twitchsdk/core/socket.h"
17 #include "twitchsdk/core/tracer.h"
18 #include "twitchsdk/core/thread.h"
19 #include "twitchsdk/core/timer.h"
24 
25 
26 namespace ttv
27 {
28  class TaskRunner;
29  class User;
30  class PubSubClient;
31  class PubSubTopicListenerHelper;
32 
33  namespace pubsub
34  {
35  struct ClientMessage;
36  struct ServerMessage;
38  struct ConnectServerMessage;
43  struct ShutdownServerMessage;
44  }
45 }
46 
47 // TODO: Add support for anonymous users
48 
87 {
88 public:
90  {
91  enum Enum
92  {
95  };
96  };
97 
99  {
100  enum Enum
101  {
103  OnDemand
104  };
105  };
106 
107  class IListener
108  {
109  public:
114  virtual void OnStateChanged(PubSubClient* source, PubSubState state, TTV_ErrorCode ec) = 0;
115  };
116 
118  {
119  public:
124  virtual void OnTopicSubscribeStateChanged(PubSubClient* source, const std::string& topic, SubscribeState::Enum state, TTV_ErrorCode ec) = 0;
128  virtual void OnTopicMessageReceived(PubSubClient* source, const std::string& topic, const json::Value& msg) = 0;
133  virtual void OnTopicListenerRemoved(PubSubClient* source, const std::string& topic, TTV_ErrorCode ec) = 0;
134  };
135 
136  typedef std::function<void(PubSubClient* source, TTV_ErrorCode ec)> SendMessageCallback;
137 
138 public:
139  PubSubClient(std::shared_ptr<User> user);
140  virtual ~PubSubClient();
141 
142  std::shared_ptr<User> GetUser();
143  PubSubState GetConnectionState() const { return mConnectionState.client; }
144 
145  // Subscription for the connection state of the PubSub component.
146  void AddListener(std::shared_ptr<IListener> listener);
147  void RemoveListener(std::shared_ptr<IListener> listener);
148 
149  TTV_ErrorCode Initialize() override;
150  virtual TTV_ErrorCode Connect();
151  TTV_ErrorCode Disconnect();
152 
153  TTV_ErrorCode SetConnectionPreference(ConnectionPreference::Enum preference);
154 
155  TTV_ErrorCode SendMessage(const json::Value& jMessage, SendMessageCallback callback);
156 
157  // Subscription for subscriptions about topic events
158  TTV_ErrorCode AddTopicListener(const std::string& topic, std::shared_ptr<ITopicListener> listener);
159  TTV_ErrorCode RemoveTopicListener(const std::string& topic, std::shared_ptr<ITopicListener> listener);
160 
161  // Component overrides
162  TTV_ErrorCode Shutdown() override;
163  virtual void Update() override;
164 
165  // UserComponent overrides
166  virtual std::string GetLoggerName() const override;
167 
168  static std::string GetComponentName() { return "ttv::PubSubClient"; }
169 
170 private:
171  struct Topic
172  {
173  Topic();
174 
175  std::string topic;
177  };
178 
179  struct TopicState
180  {
182  };
183 
185  {
186  public:
188 
189  // PubSubClientConnection::IListener Implementation
190  virtual void OnReconnectReceived(PubSubClientConnection* connection) override;
191  virtual void OnConnectionStateChanged(PubSubClientConnection* connection, PubSubState state, TTV_ErrorCode ec) override;
192  virtual void OnTopicSubscriptionChanged(PubSubClientConnection* connection, const std::string& topic, PubSubClientConnection::TopicSubscriptionState::Enum state, TTV_ErrorCode ec) override;
193  virtual void OnTopicMessageReceived(PubSubClientConnection* connection, const std::string& topic, const json::Value& message) override;
194  virtual void OnPongTimeout(PubSubClientConnection* connection) override;
195  virtual void OnAuthenticationError(PubSubClientConnection* connection, TTV_ErrorCode ec, const std::shared_ptr<const OAuthToken>& authToken) override;
196 
197  private:
199  };
200 
201  // PubSubClientConnection::IListener Implementation
202  void OnReconnectReceived(PubSubClientConnection* connection);
203  void OnConnectionStateChanged(PubSubClientConnection* connection, PubSubState state, TTV_ErrorCode ec);
204  void OnTopicSubscriptionChanged(PubSubClientConnection* connection, const std::string& topic, PubSubClientConnection::TopicSubscriptionState::Enum state, TTV_ErrorCode ec);
205  void OnTopicMessageReceived(PubSubClientConnection* connection, const std::string& topic, const json::Value& message);
206  void OnPongTimeout(PubSubClientConnection* connection);
207  void OnAuthenticationEror(PubSubClientConnection* connection, TTV_ErrorCode ec, const std::shared_ptr<const OAuthToken>& authToken);
208 
209  // Component overrides
210  virtual bool CheckShutdown() override;
211  virtual void CompleteShutdown() override;
212 
213  bool AnyConnected() const;
214  bool MainConnected() const;
215  void ThreadProc();
216  void SetConnectionState(PubSubState state, TTV_ErrorCode ec);
217 
218  void UpdateTopicSubscription(const std::string& topic);
219  void PerformReconnect();
220  TTV_ErrorCode SyncTopicSubscriptions();
221  SubscribeState::Enum GetEffectiveTopicState(const std::string& topic);
222 
223  TTV_ErrorCode ProcessRequestQueue();
224  TTV_ErrorCode ProcessConnectionPreference(std::shared_ptr<pubsub::ConnectionPreferenceServerMessage> msg);
225  TTV_ErrorCode ProcessConnect(std::shared_ptr<pubsub::ConnectServerMessage> msg);
226  TTV_ErrorCode ProcessDisconnect(std::shared_ptr<pubsub::DisconnectServerMessage> msg);
227  TTV_ErrorCode ProcessSendMessage(std::shared_ptr<pubsub::SendMessageServerMessage> msg);
228  TTV_ErrorCode ProcessSubscribeToTopic(std::shared_ptr<pubsub::SubscribeToTopicServerMessage> msg);
229  TTV_ErrorCode ProcessUnsubscribeFromTopic(std::shared_ptr<pubsub::UnsubscribeFromTopicServerMessage> msg);
230  TTV_ErrorCode ProcessShutdown(std::shared_ptr<pubsub::ShutdownServerMessage> msg);
231 
232  TTV_ErrorCode PerformDisconnect();
233  TTV_ErrorCode ScheduleConnect(TTV_ErrorCode ec);
234  TTV_ErrorCode AttemptConnection();
235 
238 
239  std::map<std::string, std::shared_ptr<Topic>> mTopics;
240 
241  std::shared_ptr<IThread> mThread;
242  std::shared_ptr<ConnectionListener> mConnectionListener;
243  std::shared_ptr<PubSubClientConnection> mConnection;
244  std::shared_ptr<PubSubClientConnection> mDyingConnection;
251 };
252 
253 
258  public std::enable_shared_from_this<PubSubTopicListenerHelper>
259 {
260 public:
261  enum class State
262  {
263  Initialized,
264  ShuttingDown,
265  Shutdown,
266  };
267 
268 public:
269  PubSubTopicListenerHelper(std::shared_ptr<PubSubClient> pubsub, std::shared_ptr<PubSubClient::ITopicListener> listener);
270  virtual ~PubSubTopicListenerHelper();
271 
272  State GetState() const { return mState; }
273  PubSubClient::SubscribeState::Enum GetSubscriptionState(const std::string& topic);
274 
275  TTV_ErrorCode Subscribe(const std::string& topic);
276  TTV_ErrorCode Unsubscribe(const std::string& topic);
277  bool ContainsTopic(const std::string& topic) const;
278 
279  void Shutdown();
280 
281  // PubSubClient::ITopicListener implementation
282  virtual void OnTopicSubscribeStateChanged(PubSubClient* source, const std::string& topic, PubSubClient::SubscribeState::Enum state, TTV_ErrorCode ec) override;
283  virtual void OnTopicMessageReceived(PubSubClient* source, const std::string& topic, const json::Value& msg) override;
284  virtual void OnTopicListenerRemoved(PubSubClient* source, const std::string& topic, TTV_ErrorCode ec) override;
285 
286 protected:
287  struct Entry
288  {
291  };
292 
293  std::map<std::string, Entry> mSubscriptionStates;
294  std::shared_ptr<PubSubClient> mPubSub;
295  std::weak_ptr<PubSubClient::ITopicListener> mListener;
297 };
Definition: timer.h:134
ConnectionPreference::Enum mConnectionPreference
Definition: pubsubclient.h:249
Enum
Definition: pubsubclientconnection.h:51
Enum
Definition: pubsubclient.h:100
Definition: pubsubclientmessages.h:113
EventSource< ITopicListener > listeners
Definition: pubsubclient.h:176
Definition: pubsubclient.h:98
Definition: pubsubclientmessages.h:155
Definition: pubsubclientconnection.h:46
State mState
Definition: pubsubclient.h:296
std::weak_ptr< PubSubClient::ITopicListener > mListener
Definition: pubsubclient.h:295
Enum
Definition: pubsubclient.h:91
static std::string GetComponentName()
Definition: pubsubclient.h:168
Definition: pubsubclient.h:287
SubscribeState::Enum state
The current state of the connection.
Definition: pubsubclient.h:181
JSON (JavaScript Object Notation).
Definition: adsapi.h:16
std::shared_ptr< ConnectionListener > mConnectionListener
Definition: pubsubclient.h:242
bool subscriptionDesired
Definition: pubsubclient.h:290
PubSubClient * mPubSub
Definition: pubsubclient.h:198
Represents a JSON value.
Definition: value.h:114
std::shared_ptr< PubSubClientConnection > mConnection
The active connection.
Definition: pubsubclient.h:243
std::shared_ptr< IThread > mThread
Definition: pubsubclient.h:241
Definition: pubsubclient.h:86
Definition: eventsource.h:18
Definition: pubsubclientconnection.h:60
Definition: pubsubclientmessages.h:130
Definition: pubsubclientmessages.h:147
uint32_t TTV_ErrorCode
Definition: errortypes.h:30
PubSubState
Definition: coretypes.h:152
Definition: component.h:87
std::string topic
Definition: pubsubclient.h:175
std::function< void()> ThreadProc
Definition: thread.h:22
PubSubClient::SubscribeState::Enum state
Definition: pubsubclient.h:289
Definition: pubsubclient.h:117
bool mConnectionDesired
Whether or not the client has called Connect().
Definition: pubsubclient.h:250
Definition: pubsubclient.h:179
Definition: pubsubclientmessages.h:108
Definition: pubsubclient.h:257
The client must manually call Connect() and Disconnect().
Definition: pubsubclient.h:102
Definition: concurrentqueue.h:16
Definition: pubsubclient.h:89
ConcurrentQueue< std::shared_ptr< pubsub::ClientMessage > > mIncomingQueue
Definition: pubsubclient.h:236
Definition: pubsubclientmessages.h:35
std::map< std::string, Entry > mSubscriptionStates
Definition: pubsubclient.h:293
ConcurrentQueue< std::shared_ptr< pubsub::ServerMessage > > mOutgoingQueue
Definition: pubsubclient.h:237
std::map< std::string, std::shared_ptr< Topic > > mTopics
Definition: pubsubclient.h:239
PubSubState GetConnectionState() const
Definition: pubsubclient.h:143
std::shared_ptr< PubSubClient > mPubSub
Definition: pubsubclient.h:294
EventSource< IListener > mListeners
Definition: pubsubclient.h:245
ClientServerValue< PubSubState > mConnectionState
Definition: pubsubclient.h:248
State
Definition: pubsubclient.h:261
Definition: pubsubclientmessages.h:138
json::FastWriter mJsonWriter
Definition: pubsubclient.h:246
Definition: pubsubclient.h:107
Definition: pubsubclient.h:184
RetryTimer mConnectionRetryTimer
Definition: pubsubclient.h:247
State GetState() const
Definition: pubsubclient.h:272
Outputs a Value in JSON format without formatting (not human friendly).
Definition: writer.h:31
std::shared_ptr< PubSubClientConnection > mDyingConnection
The connection that might be alive for a short time after a RECONNECT is received from the server...
Definition: pubsubclient.h:244
Definition: pubsubclientmessages.h:120
Definition: pubsubclientmessages.h:125
Definition: pubsubclient.h:171
std::function< void(PubSubClient *source, TTV_ErrorCode ec)> SendMessageCallback
Definition: pubsubclient.h:136