MetaSoul

Loading...
Searching...
No Matches
sio_client_impl.h
Go to the documentation of this file.
1// Modifications Copyright 2022-current EmoShape. All Rights Reserved
2
3#ifndef EMOSHAPEIO_CLIENT_IMPL_H
4#define EMOSHAPEIO_CLIENT_IMPL_H
5
6#ifndef SIO_TLS
7#define SIO_TLS 0
8#endif
9
10/* This disables two things:
11 1) error 4503 where MSVC complains about
12 decorated names being too long. There's no way around
13 this.
14 2) We also disable a security error triggered by
15 websocketpp not using checked iterators.
16*/
17#ifdef _MSC_VER
18#pragma warning(disable : 4503)
19#define _SCL_SECURE_NO_WARNINGS
20#endif
21
22/* For this code, we will use standalone ASIO
23 and websocketpp in C++11 mode only */
24#define ASIO_STANDALONE
25#define _WEBSOCKETPP_CPP11_STL_
26
27#include <cstdint>
28#define INTIALIZER(__TYPE__)
29
30#include "CoreMinimal.h"
31
32#if PLATFORM_WINDOWS
33//#define WIN32_LEAN_AND_MEAN
34#include "Windows/WindowsHWrapper.h"
35#include "Windows/AllowWindowsPlatformAtomics.h"
36#endif
37
38#include <websocketpp/client.hpp>
39#include <asio/system_timer.hpp>
40
41#if defined(DEBUG)
42 #if SIO_TLS
43 #define UI UI_ST
44 THIRD_PARTY_INCLUDES_START
45 #include "openssl/hmac.h"
46 #include <websocketpp/config/debug_asio.hpp>
47 typedef websocketpp::config::debug_asio_tls client_config_tls;
48 THIRD_PARTY_INCLUDES_END
49 #undef UI
50 #endif //SIO_TLS
51 #include <websocketpp/config/debug_asio_no_tls.hpp>
52 typedef websocketpp::config::debug_asio client_config;
53#else
54 #if SIO_TLS
55 #define UI UI_ST
56 THIRD_PARTY_INCLUDES_START
57 #include "openssl/hmac.h"
58 #include <websocketpp/config/asio_client.hpp>
59 typedef websocketpp::config::asio_tls_client client_config_tls;
60 THIRD_PARTY_INCLUDES_END
61 #undef UI
62 #endif //SIO_TLS
63 #include <websocketpp/config/asio_no_tls_client.hpp>
64 typedef websocketpp::config::asio_client client_config;
65#endif //DEBUG
66#include <asio/deadline_timer.hpp>
67
68#include <memory>
69#include <map>
70#include <thread>
71
72#include "EmoShapeSubSystem/EmoShapeIOLib/Public/sio_client.h"
73#include "sio_packet.h"
74
75#if PLATFORM_WINDOWS
76#include "Windows/HideWindowsPlatformAtomics.h"
77#endif
78
79 namespace emoshapeio
80 {
81 using namespace websocketpp;
82
83 typedef websocketpp::client<client_config> client_type_no_tls;
84#if SIO_TLS
85 typedef websocketpp::client<client_config_tls> client_type_tls;
86#endif
87
88 class client_impl_base {
89
90 public:
91 enum con_state
92 {
93 con_opening,
94 con_opened,
95 con_closing,
96 con_closed
97 };
98
99 client_impl_base() {}
100 virtual void template_init() {};
101
102 virtual ~client_impl_base() {}
103
104 // listeners and event bindings. (see SYNTHESIS_SETTER below)
105 virtual void set_open_listener(client::con_listener const&) {};
106 virtual void set_fail_listener(client::con_listener const&) {};
107 virtual void set_reconnect_listener(client::reconnect_listener const&) {};
108 virtual void set_reconnecting_listener(client::con_listener const&) {};
109 virtual void set_close_listener(client::close_listener const&) {};
110 virtual void set_socket_open_listener(client::socket_listener const&) {};
111 virtual void set_socket_close_listener(client::socket_listener const&) {};
112
113 // used by emoshapeio::client
114 virtual void clear_con_listeners() {};
115 virtual void clear_socket_listeners() {};
116 virtual void connect(const string& uri, const map<string, string>& query, const map<string, string>& headers, const std::string& path = "socket.io") {};
117
118 virtual emoshapeio::socket::ptr const& socket(const std::string& nsp) = 0;
119 virtual void close() {};
120 virtual void sync_close() {};
121 virtual bool opened() const { return false; };
122 virtual std::string const& get_sessionid() const = 0;
123 virtual void set_reconnect_attempts(unsigned attempts) {};
124 virtual void set_reconnect_delay(unsigned millis) {};
125 virtual void set_reconnect_delay_max(unsigned millis) {};
126
127 // used by emoshapeio::socket
128 virtual void send(packet& p) {};
129 virtual void remove_socket(std::string const& nsp) {};
130 virtual asio::io_service& get_io_service() = 0;
131 virtual void on_socket_closed(std::string const& nsp) {};
132 virtual void on_socket_opened(std::string const& nsp) {};
133
134 virtual void set_logs_default() {};
135 virtual void set_logs_quiet() {};
136 virtual void set_logs_verbose() {};
137
138 virtual std::string const& get_current_url() const = 0;
139
140 // used for selecting whether or not to use TLS
141 static bool is_tls(const std::string& uri);
142
143#if SIO_TLS
144 virtual void set_verify_mode(int mode) {};
145#endif
146
147 protected:
148 // Wrap protected member functions of emoshapeio::socket because only client_impl_base is friended.
149 emoshapeio::socket* new_socket(std::string const&);
150 void socket_on_message_packet(emoshapeio::socket::ptr&, packet const&);
151 typedef void (emoshapeio::socket::* socket_void_fn)(void);
152 inline socket_void_fn socket_on_close() { return &emoshapeio::socket::on_close; }
153 inline socket_void_fn socket_on_disconnect() { return &emoshapeio::socket::on_disconnect; }
154 inline socket_void_fn socket_on_open() { return &emoshapeio::socket::on_open; }
155 };
156
157 template<typename client_type>
158 class client_impl : public client_impl_base {
159 public:
160 typedef typename client_type::message_ptr message_ptr;
161
162 client_impl();
163 void template_init() override; // template-specific initialization
164
165 ~client_impl();
166
167 //set listeners and event bindings.
168 void connect(const std::string& uri, const std::map<std::string, std::string>& queryString,
169 const std::map<std::string, std::string>& httpExtraHeaders, const std::string& path = "socket.io");
170
171 emoshapeio::socket::ptr const& socket(const std::string& nsp);
172
173 // Closes the connection
174 void close();
175
176 void sync_close();
177
178 bool opened() const { return m_con_state == con_opened; }
179
180 std::string const& get_sessionid() const { return m_sid; }
181
182 std::string const& get_current_url() const { return m_base_url; }
183
184 void set_reconnect_attempts(unsigned attempts) { m_reconn_attempts = attempts; }
185
186 void set_reconnect_delay(unsigned millis) { m_reconn_delay = millis; if (m_reconn_delay_max < millis) m_reconn_delay_max = millis; }
187
188 void set_reconnect_delay_max(unsigned millis) { m_reconn_delay_max = millis; if (m_reconn_delay > millis) m_reconn_delay = millis; }
189
190 void set_logs_default();
191
192 void set_logs_quiet();
193
194 void set_logs_verbose();
195
196#define SYNTHESIS_SETTER(__TYPE__,__FIELD__) \
197 void set_##__FIELD__(__TYPE__ const& l) \
198 { m_##__FIELD__ = l;}
199
200 SYNTHESIS_SETTER(client::con_listener, open_listener)
201
202 SYNTHESIS_SETTER(client::con_listener, fail_listener)
203
204 SYNTHESIS_SETTER(client::reconnect_listener, reconnect_listener)
205
206 SYNTHESIS_SETTER(client::con_listener, reconnecting_listener)
207
208 SYNTHESIS_SETTER(client::close_listener, close_listener)
209
210 SYNTHESIS_SETTER(client::socket_listener, socket_open_listener)
211
212 SYNTHESIS_SETTER(client::socket_listener, socket_close_listener)
213#undef SYNTHESIS_SETTER
214
215#if SIO_TLS
216 void set_verify_mode(int mode) override;
217#endif
218
219 public:
220 void send(packet& p);
221
222 void remove_socket(std::string const& nsp);
223
224 asio::io_service& get_io_service();
225
226 void on_socket_closed(std::string const& nsp);
227
228 void on_socket_opened(std::string const& nsp);
229
230 private:
231 void run_loop();
232
233 void connect_impl(const std::string& uri, const std::string& query);
234
235 void close_impl(close::status::value const& code, std::string const& reason);
236
237 void send_impl(std::shared_ptr<const std::string> const& payload_ptr, frame::opcode::value opcode);
238
239 void ping(const asio::error_code& ec);
240
241 void timeout_pong(const asio::error_code& ec);
242
243 void timeout_reconnect(asio::error_code const& ec);
244
245 unsigned next_delay() const;
246
247 socket::ptr get_socket_locked(std::string const& nsp);
248
249 void sockets_invoke_void(void (emoshapeio::socket::* fn)(void));
250
251 void on_decode(packet const& pack);
252 void on_encode(bool isBinary, shared_ptr<const string> const& payload);
253
254 //websocket callbacks
255 void on_fail(connection_hdl con);
256
257 void on_open(connection_hdl con);
258
259 void on_close(connection_hdl con);
260
261 void on_message(connection_hdl con, message_ptr msg);
262
263 //socketio callbacks
264 void on_handshake(message::ptr const& message);
265
266 void on_ping();
267
268 void reset_states();
269
270 void clear_timers();
271
272 // Percent encode query string
273 std::string encode_query_string(const std::string& query);
274
275 // Connection pointer for client functions.
276 connection_hdl m_con;
277 client_type m_client;
278
279 // Socket.IO server settings
280 std::string m_sid;
281 std::string m_base_url;
282 std::string m_query_string;
283 std::map<std::string, std::string> m_http_headers;
284
285 unsigned int m_ping_interval;
286 unsigned int m_ping_timeout;
287
288 std::unique_ptr<std::thread> m_network_thread;
289
290 packet_manager m_packet_mgr;
291
292 std::unique_ptr<asio::steady_timer> m_ping_timeout_timer;
293
294 std::unique_ptr<asio::steady_timer> m_reconn_timer;
295
296 con_state m_con_state;
297
298 client::con_listener m_open_listener;
299 client::con_listener m_fail_listener;
300 client::con_listener m_reconnecting_listener;
301 client::reconnect_listener m_reconnect_listener;
302 client::close_listener m_close_listener;
303
304 client::socket_listener m_socket_open_listener;
305 client::socket_listener m_socket_close_listener;
306
307 std::map<const std::string, socket::ptr> m_sockets;
308
309 std::mutex m_socket_mutex;
310
311 unsigned m_reconn_delay;
312
313 unsigned m_reconn_delay_max;
314
315 unsigned m_reconn_attempts;
316
317 unsigned m_reconn_made;
318
319 //passthrough path of plugin
320 std::string m_path;
321
322#if SIO_TLS
323 int verify_mode = -1;
324#endif
325
326 friend class emoshapeio::client;
327 friend class emoshapeio::socket;
328 };
329}
330#endif // EMOSHAPEIO_CLIENT_IMPL_H
emoshapeio::client_impl_base
Definition sio_client_impl.h:88
emoshapeio::client_impl_base::remove_socket
virtual void remove_socket(std::string const &nsp)
Definition sio_client_impl.h:129
emoshapeio::client_impl_base::set_reconnecting_listener
virtual void set_reconnecting_listener(client::con_listener const &)
Definition sio_client_impl.h:108
emoshapeio::client_impl_base::get_current_url
virtual std::string const & get_current_url() const =0
emoshapeio::client_impl_base::socket_on_message_packet
void socket_on_message_packet(emoshapeio::socket::ptr &, packet const &)
Definition sio_client_impl.cpp:740
emoshapeio::client_impl_base::set_fail_listener
virtual void set_fail_listener(client::con_listener const &)
Definition sio_client_impl.h:106
emoshapeio::client_impl_base::on_socket_closed
virtual void on_socket_closed(std::string const &nsp)
Definition sio_client_impl.h:131
emoshapeio::client_impl_base::set_socket_close_listener
virtual void set_socket_close_listener(client::socket_listener const &)
Definition sio_client_impl.h:111
emoshapeio::client_impl_base::socket_on_disconnect
socket_void_fn socket_on_disconnect()
Definition sio_client_impl.h:153
emoshapeio::client_impl_base::socket
virtual emoshapeio::socket::ptr const & socket(const std::string &nsp)=0
emoshapeio::client_impl_base::client_impl_base
client_impl_base()
Definition sio_client_impl.h:99
emoshapeio::client_impl_base::opened
virtual bool opened() const
Definition sio_client_impl.h:121
emoshapeio::client_impl_base::con_state
con_state
Definition sio_client_impl.h:92
emoshapeio::client_impl_base::con_opened
@ con_opened
Definition sio_client_impl.h:94
emoshapeio::client_impl_base::con_closing
@ con_closing
Definition sio_client_impl.h:95
emoshapeio::client_impl_base::con_opening
@ con_opening
Definition sio_client_impl.h:93
emoshapeio::client_impl_base::con_closed
@ con_closed
Definition sio_client_impl.h:96
emoshapeio::client_impl_base::send
virtual void send(packet &p)
Definition sio_client_impl.h:128
emoshapeio::client_impl_base::get_io_service
virtual asio::io_service & get_io_service()=0
emoshapeio::client_impl_base::get_sessionid
virtual std::string const & get_sessionid() const =0
emoshapeio::client_impl_base::set_open_listener
virtual void set_open_listener(client::con_listener const &)
Definition sio_client_impl.h:105
emoshapeio::client_impl_base::template_init
virtual void template_init()
Definition sio_client_impl.h:100
emoshapeio::client_impl_base::~client_impl_base
virtual ~client_impl_base()
Definition sio_client_impl.h:102
emoshapeio::client_impl_base::set_reconnect_delay
virtual void set_reconnect_delay(unsigned millis)
Definition sio_client_impl.h:124
emoshapeio::client_impl_base::sync_close
virtual void sync_close()
Definition sio_client_impl.h:120
emoshapeio::client_impl_base::new_socket
emoshapeio::socket * new_socket(std::string const &)
Definition sio_client_impl.cpp:735
emoshapeio::client_impl_base::connect
virtual void connect(const string &uri, const map< string, string > &query, const map< string, string > &headers, const std::string &path="socket.io")
Definition sio_client_impl.h:116
emoshapeio::client_impl_base::set_logs_default
virtual void set_logs_default()
Definition sio_client_impl.h:134
emoshapeio::client_impl_base::is_tls
static bool is_tls(const std::string &uri)
Definition sio_client_impl.cpp:714
emoshapeio::client_impl_base::on_socket_opened
virtual void on_socket_opened(std::string const &nsp)
Definition sio_client_impl.h:132
emoshapeio::client_impl_base::socket_on_open
socket_void_fn socket_on_open()
Definition sio_client_impl.h:154
emoshapeio::client_impl_base::close
virtual void close()
Definition sio_client_impl.h:119
emoshapeio::client_impl_base::clear_con_listeners
virtual void clear_con_listeners()
Definition sio_client_impl.h:114
emoshapeio::client_impl_base::socket_void_fn
void(emoshapeio::socket::* socket_void_fn)(void)
Definition sio_client_impl.h:151
emoshapeio::client_impl_base::set_reconnect_attempts
virtual void set_reconnect_attempts(unsigned attempts)
Definition sio_client_impl.h:123
emoshapeio::client_impl_base::set_logs_verbose
virtual void set_logs_verbose()
Definition sio_client_impl.h:136
emoshapeio::client_impl_base::set_reconnect_listener
virtual void set_reconnect_listener(client::reconnect_listener const &)
Definition sio_client_impl.h:107
emoshapeio::client_impl_base::set_logs_quiet
virtual void set_logs_quiet()
Definition sio_client_impl.h:135
emoshapeio::client_impl_base::set_close_listener
virtual void set_close_listener(client::close_listener const &)
Definition sio_client_impl.h:109
emoshapeio::client_impl_base::clear_socket_listeners
virtual void clear_socket_listeners()
Definition sio_client_impl.h:115
emoshapeio::client_impl_base::set_reconnect_delay_max
virtual void set_reconnect_delay_max(unsigned millis)
Definition sio_client_impl.h:125
emoshapeio::client_impl_base::socket_on_close
socket_void_fn socket_on_close()
Definition sio_client_impl.h:152
emoshapeio::client_impl_base::set_socket_open_listener
virtual void set_socket_open_listener(client::socket_listener const &)
Definition sio_client_impl.h:110
emoshapeio::client_impl
Definition sio_client_impl.h:158
emoshapeio::client_impl::sync_close
void sync_close()
Definition sio_client_impl.cpp:189
emoshapeio::client_impl::get_sessionid
std::string const & get_sessionid() const
Definition sio_client_impl.h:180
emoshapeio::client_impl::set_reconnect_delay_max
void set_reconnect_delay_max(unsigned millis)
Definition sio_client_impl.h:188
emoshapeio::client_impl::close
void close()
Definition sio_client_impl.cpp:181
emoshapeio::client_impl::socket
friend class emoshapeio::socket
Definition sio_client_impl.h:327
emoshapeio::client_impl::remove_socket
void remove_socket(std::string const &nsp)
Definition sio_client_impl.cpp:228
emoshapeio::client_impl::set_logs_quiet
void set_logs_quiet()
Definition sio_client_impl.cpp:209
emoshapeio::client_impl::on_socket_opened
void on_socket_opened(std::string const &nsp)
Definition sio_client_impl.cpp:251
emoshapeio::client_impl::set_logs_default
void set_logs_default()
Definition sio_client_impl.cpp:202
emoshapeio::client_impl::client_impl
client_impl()
Definition sio_client_impl.cpp:54
emoshapeio::client_impl::message_ptr
client_type::message_ptr message_ptr
Definition sio_client_impl.h:160
emoshapeio::client_impl::template_init
void template_init() override
emoshapeio::client_impl::send
void send(packet &p)
Definition sio_client_impl.cpp:222
emoshapeio::client_impl::set_reconnect_attempts
void set_reconnect_attempts(unsigned attempts)
Definition sio_client_impl.h:184
emoshapeio::client_impl::on_socket_closed
void on_socket_closed(std::string const &nsp)
Definition sio_client_impl.cpp:245
emoshapeio::client_impl::set_reconnect_delay
void set_reconnect_delay(unsigned millis)
Definition sio_client_impl.h:186
emoshapeio::client_impl::opened
bool opened() const
Definition sio_client_impl.h:178
emoshapeio::client_impl::set_logs_verbose
void set_logs_verbose()
Definition sio_client_impl.cpp:215
emoshapeio::client_impl::connect
void connect(const std::string &uri, const std::map< std::string, std::string > &queryString, const std::map< std::string, std::string > &httpExtraHeaders, const std::string &path="socket.io")
Definition sio_client_impl.cpp:94
emoshapeio::client_impl::get_io_service
asio::io_service & get_io_service()
Definition sio_client_impl.cpp:239
emoshapeio::client_impl::get_current_url
std::string const & get_current_url() const
Definition sio_client_impl.h:182
emoshapeio::client_impl::client
friend class emoshapeio::client
Definition sio_client_impl.h:326
emoshapeio::client_impl::~client_impl
~client_impl()
Definition sio_client_impl.cpp:87
emoshapeio::client
Definition sio_client.h:13
emoshapeio::client::reconnect_listener
std::function< void(unsigned, unsigned)> reconnect_listener
Definition sio_client.h:25
emoshapeio::client::close_listener
std::function< void(close_reason const &reason) close_listener)
Definition sio_client.h:23
emoshapeio::client::con_listener
std::function< void(void)> con_listener
Definition sio_client.h:21
emoshapeio::client::socket_listener
std::function< void(std::string const &nsp) socket_listener)
Definition sio_client.h:27
emoshapeio::message::ptr
std::shared_ptr< message > ptr
Definition sio_message.h:37
emoshapeio::packet
Definition sio_packet.h:20
emoshapeio::socket
Definition sio_socket.h:49
emoshapeio::socket::on_disconnect
void on_disconnect()
Definition sio_socket.cpp:626
emoshapeio::socket::ptr
std::shared_ptr< socket > ptr
Definition sio_socket.h:57
emoshapeio::socket::on_close
void on_close()
Definition sio_socket.cpp:611
emoshapeio::socket::on_open
void on_open()
Definition sio_socket.cpp:616
emoshapeio
Definition sio_client_impl.cpp:51
emoshapeio::client_type_no_tls
websocketpp::client< client_config > client_type_no_tls
Definition sio_client_impl.h:83
sio_client.h
SYNTHESIS_SETTER
#define SYNTHESIS_SETTER(__TYPE__, __FIELD__)
Definition sio_client_impl.h:196
client_config
websocketpp::config::asio_client client_config
Definition sio_client_impl.h:64
sio_packet.h