HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NET_WebSocketSet.h
Go to the documentation of this file.
1 /*
2  * POPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: NET_WebSocketSet.h
7  *
8  * COMMENTS:
9  *
10  */
11 
12 #ifndef __NET_WEBSOCKETSET_H__
13 #define __NET_WEBSOCKETSET_H__
14 
15 #include "NET_API.h"
16 
17 #include "NET_WebSocket.h"
18 
19 #include <UT/UT_Array.h>
20 #include <UT/UT_ArrayStringMap.h>
21 #include <UT/UT_Map.h>
22 #include <UT/UT_SharedPtr.h>
23 #include <UT/UT_StringHolder.h>
24 #include <UT/UT_Url.h>
25 
26 #include <chrono>
27 
28 class NET_WebSocketSet;
29 
30 /// The WebSocketSet is responsible for creating and managing one or more
31 /// client-side web socket connections.
32 ///
33 /// The methods for sending data assume a "fire and forget" approach, with no
34 /// connection to data coming back through the sockets. As such, these methods
35 /// should be strictly non-blocking.
36 class NET_API NET_WebSocketSet
37 {
38  friend class NET_WebSocketItem;
39 
40 public:
41  /// @brief Describes an event that has occured.
42  class NET_API Event
43  {
44  public:
45  enum Type
46  {
56  MESSAGE_RECEIVE_ERROR
57  };
58 
59  Event() = default;
60  Event(const Type& type, const UT_StringHolder& id, const NET_Time& t)
61  : myId(id)
62  , myType(type)
63  , myUrl()
64  , myTimestamp(t)
65  , myError()
66  , myMessage()
67  {
68  }
69 
70  friend std::ostream& operator<<(std::ostream& os, const Event ev)
71  {
72  // timestamp: TYPE(id) url message error
73 
74  os << ev.myTimestamp.toUTCString();
75  os << ": ";
76 
77  switch (ev.myType)
78  {
79  case CONNECTED:
80  os << "CONNECTED";
81  break;
82  case CONNECT_ERROR:
83  os << "CONNECT ERROR";
84  break;
85  case DISCONNECTED:
86  os << "DISCONNECTED";
87  break;
88  case DISCONNECT_ERROR:
89  os << "DISCONNECT ERROR";
90  break;
91  case MESSAGE_SENT:
92  os << "MESSAGE SENT";
93  break;
94  case MESSAGE_SEND_ERROR:
95  os << "MESSAGE SEND ERROR";
96  break;
97  case MESSAGE_RECEIVED:
98  os << "MESSAGE RECEIVED";
99  break;
100  case MESSAGE_RECEIVE_ERROR:
101  os << "MESSAGE RECEIVE ERROR";
102  break;
103  default:
104  os << "UNKNOWN";
105  break;
106  };
107 
108  os << "(" << ev.myId << ") " << ev.myUrl.toString();
109  os << " Msg='" << ev.myMessage << "' Error='" << ev.myError << "'";
110 
111  return os;
112  }
113 
114  /// @brief The type of event that occured.
116 
117  /// @brief The url that the event originated from.
119  /// @brief The connection id the event originated from.
121  /// @brief The time at which the event occured.
123  /// @brief The error message if this is an error that occured.
125  /// @brief The message for the event. In the case of a message event
126  /// this
127  /// is the read in event. In all other cases this describes the
128  /// details of the event in English.
130  };
131 
132  /// @brief Connect to a remote server.
133  ///
134  /// @param id The id of the connected websocket.
135  /// @param url The url of the websocket.
136  /// @param timeout The timeout to use before giving up on connecting.
137  ///
138  /// @return True if a connected websocket was produced.
139  bool connect(
140  const UT_StringRef& id,
141  const UT_Url& url,
142  const std::chrono::milliseconds& timeout);
143  /// @brief Use this function to poll for new events if there are currently
144  /// no queued events.
145  ///
146  /// @param ev The object describing the event.
147  /// @param timeout A timeout of 0 means only return an event if there is one
148  // waiting. A timeout < 0 can be used to wait forever for
149  // an event.
150  ///
151  /// @return True if this function is returning an event.
152  bool getNextEvent(Event& ev, const std::chrono::milliseconds& timeout);
153  /// @brief Close a specific connection based on the provided id. A
154  /// DISCONNECTED or DISCONNECT_ERROR will be generated.
155  ///
156  /// @param id The id to identify which connection to close.
157  ///
158  /// @return True if the connection was disconnected.
159  bool disconnect(const UT_StringHolder& id);
160  /// @brief Disconnect all connections this manager currently manages.
161  void disconnectAll();
162  /// @brief Send a message to a particular connection.
163  /// This generates a MESSAGE_SENT or MESSAGE_SEND_ERROR.
164  ///
165  /// @param id The id of the connection to send the message too.
166  /// @param wbuf The message to send.
167  void sendMessage(const UT_StringHolder& id, const UT_StringHolder& message);
168 
169 private:
170  class NET_API Item : public NET_WebSocket
171  {
172  public:
173  Item(NET_WebSocketSet& socket_set, const UT_StringHolder& id);
174 
175  void onEvent(const Event& ev) override;
176 
177  const UT_StringHolder& id() const { return myId; }
178 
179  private:
180  NET_WebSocketSet& mySocketSet;
181  UT_StringHolder myId;
182  };
183 
184  /// @brief Callback for each an every websocket event. Currently this
185  /// translates and queues the event to be picked up later.
186  ///
187  /// @param ws The websocket the event happened on.
188  /// @param ev The object describing the event.
189  void queueEvent_(
190  NET_WebSocketSet::Item* ws,
191  const NET_WebSocket::Event& ev);
192  /// @brief Disconnect the websocket using the websocket instance itself.
193  /// This will lock the set.
194  ///
195  /// @param item The websocket instance to remove.
196  ///
197  /// @return True if the disconnect was a success.
198  bool disconnectByWS_(const UT_SharedPtr<Item>& item);
199  /// @brief Same as disconnectByWS except that this does not lock and as such
200  /// is labelled as unsafe.
201  ///
202  /// @param item The websocket item instance to remove.
203  ///
204  /// @return True if the disconnect was a success.
205  bool disconnectByWSUnsafe_(const UT_SharedPtr<Item>& item);
206 
207  UT_Lock myLock;
208  /// @brief Maps the fd to the named ids.
209  UT_Map<int, UT_StringHolder> myFDtoNamedIds;
210  /// @brief Maps the named id to fds.
211  UT_ArrayStringMap<UT_SharedPtr<Item>> myNamedIdToWebSockets;
212  /// @brief Queue of events that occured.
213  UT_Array<Event> myQueuedEvents;
214 };
215 
216 #endif // __NET_WEBSOCKETSET_H__
217 
GLuint id
Definition: glew.h:1679
Event(const Type &type, const UT_StringHolder &id, const NET_Time &t)
UT_StringHolder myId
The connection id the event originated from.
friend std::ostream & operator<<(std::ostream &os, const Event ev)
UT_StringHolder toString(unsigned format=FormattingOptions::None) const
Describes an event that has occured.
UT_StringHolder toUTCString() const
virtual void onEvent(const Event &ev)
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:28
Class used for web socket operations.
Definition: NET_WebSocket.h:47
GLsizei GLenum GLuint GLuint GLsizei GLchar * message
Definition: glew.h:2581
Definition: UT_Url.h:22
UT_StringHolder myMessage
The message for the event. In the case of a message event this is the read in event. In all other cases this describes the details of the event in English.
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
UT_StringHolder myError
The error message if this is an error that occured.
Type myType
The type of event that occured.
GLbitfield GLuint64 timeout
Definition: glew.h:6605
GLdouble GLdouble t
Definition: glew.h:1398
UT_Url myUrl
The url that the event originated from.
NET_Time myTimestamp
The time at which the event occured.