1919// json parsing for event data and payloads
2020#include < nlohmann/json.hpp>
2121
22+ #include " WinSockInit.hpp" // winsock initialization on Windows
23+
2224#include < curl/curl.h> // libcurl
2325#include " CurlGlobal.hpp" // RAII wrapper for curl_global_init and curl_global_cleanup
2426
2527// Include refactored headers
2628#include " SioClientV2.hpp" // socket.io v2 client with polling handshake
2729#include " SioClientV4.hpp" // socket.io v3/v4 client with direct websocket connection
2830
31+ void runV4Example (std::shared_ptr<spdlog::logger> console);
32+ void runV2Example (std::shared_ptr<spdlog::logger> console);
33+
34+ int main () {
35+
36+ // initialize logging
37+ auto console = spdlog::stdout_color_mt (" console" );
38+ if (console == nullptr ) {
39+ std::cerr << " [Fatal] Failed to create console logger" << std::endl;
40+ return 1 ;
41+ }
42+ spdlog::set_level (spdlog::level::trace);
43+ // console->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
44+ // console->set_pattern("[%H:%M:%S.%e] [%^%l%$] %v");
45+ spdlog::set_default_logger (console);
46+
47+ #ifdef _WIN32
48+ // Ensure WinSock is initialized before any socket operations
49+ try {
50+ WinSockInit wsi;
51+ } catch (const std::exception& ex) {
52+ console->critical (" [Fatal] WinSock initialization failed: {}" , ex.what ());
53+ return 1 ;
54+ }
55+ #endif
56+
57+ // Initialize libcurl globally; RAII wrapper ensures cleanup on exit
58+ std::unique_ptr<CurlGlobal> curlInit = nullptr ;
59+ try {
60+ curlInit = std::make_unique<CurlGlobal>();
61+ // CurlGlobal will automatically clean up when going out of scope at the end of main
62+ } catch (const std::exception& ex) {
63+ console->critical (" [Fatal] CurlGlobal initialization failed: {}" , ex.what ());
64+ return 1 ;
65+ }
66+
67+ try { // Run examples separately
68+
69+ runV4Example (console); // socket.io v3/v4 example with direct websocket connection
70+
71+ std::this_thread::sleep_for (std::chrono::seconds (1 ));
72+ console->info (" ==============================================" );
73+
74+ runV2Example (console); // socket.io v2 example with polling handshake
75+
76+ std::this_thread::sleep_for (std::chrono::seconds (2 )); // brief observe period
77+ } catch (const std::exception& ex) {
78+ console->critical (" [Fatal] {}" , ex.what ());
79+ return 2 ;
80+ }
81+
82+ return 0 ;
83+ }
84+
2985// Socket.IO v3/v4 example with direct websocket connection (no polling handshake)
30- static void runV4Example (std::shared_ptr<spdlog::logger> console)
86+ void runV4Example (std::shared_ptr<spdlog::logger> console)
3187{
3288 console->info (" [Example] Starting Socket.IO v3/v4 example" );
3389
@@ -39,36 +95,37 @@ static void runV4Example(std::shared_ptr<spdlog::logger> console)
3995 std::atomic<bool > disconnected (false ); // Atomic flag tracking whether disconnected from the server
4096
4197 // Register emit handler that logs on send
42- client.onEmit ([&client](const std::string& event, const nlohmann::json& data){
98+ client.onEmit ([&client](const std::string& event, const nlohmann::json& data) {
4399 if (auto lg = client.getLogger ()) {
44100 lg->info (" [App] Emitting {} -> {}" , event, data.dump ());
45101 }
46- });
102+ });
47103
48104 // Register handler for disconnect
49105 client.onDisconnect ([&client, &disconnected]() {
50106 if (auto lg = client.getLogger ()) {
51107 lg->info (" [App] Disconnected, scheduling cleanup" );
52- }
53- });
108+ }
109+ });
54110
55111 // Register handler to log when "server-info" event is received
56- client.on (" server-info" , [&client](const nlohmann::json& data){
112+ client.on (" server-info" , [&client](const nlohmann::json& data) {
57113 if (auto lg = client.getLogger ()) {
58114 lg->info (" [App] message received: {}" , data.dump ());
59115 }
60- });
116+ });
61117
62118 // Register handler to log any received event
63- client.onAny ([&client](const std::string& event, const nlohmann::json& data){
119+ client.onAny ([&client](const std::string& event, const nlohmann::json& data) {
64120 if (auto lg = client.getLogger ()) {
65121 lg->info (" [App] any event: {} -> {}" , event, data.dump ());
66122 }
67- });
123+ });
68124
69125 try {
70126 client.connect (" 127.0.0.1" , 3004 , " /socket.io/" );
71- } catch (const std::exception &ex) {
127+ }
128+ catch (const std::exception& ex) {
72129 console->error (" [Example][Error] V4 connect failed: {}" , ex.what ());
73130 return ;
74131 }
@@ -89,7 +146,7 @@ static void runV4Example(std::shared_ptr<spdlog::logger> console)
89146 }
90147
91148 // If connected, send
92- client.emit (" message" , nlohmann::json ({{" user" , " cpp_client_v4" }, {" text" , " Hello from v4 client!" }}));
149+ client.emit (" message" , nlohmann::json ({ {" user" , " cpp_client_v4" }, {" text" , " Hello from v4 client!" } }));
93150
94151 std::this_thread::sleep_for (std::chrono::seconds (3 ));
95152 }
@@ -99,7 +156,7 @@ static void runV4Example(std::shared_ptr<spdlog::logger> console)
99156}
100157
101158// Socket.IO v2 example with polling handshake to obtain sid, then websocket upgrade
102- static void runV2Example (std::shared_ptr<spdlog::logger> console)
159+ void runV2Example (std::shared_ptr<spdlog::logger> console)
103160{
104161 console->info (" [Example] Starting Socket.IO v2 example" );
105162
@@ -111,57 +168,58 @@ static void runV2Example(std::shared_ptr<spdlog::logger> console)
111168 std::atomic<bool > disconnected{ false }; // Atomic flag tracking whether disconnected from the server
112169
113170 // Register emit handler that logs on send
114- client.onEmit ([&client](const std::string& event, const nlohmann::json& data){
171+ client.onEmit ([&client](const std::string& event, const nlohmann::json& data) {
115172 if (auto lg = client.getLogger ()) {
116173 lg->info (" [App] Emitting {} -> {}" , event, data.dump ());
117174 }
118- });
175+ });
119176
120177 // Register handler for disconnect
121- client.onDisconnect ([&client, &disconnected](){
178+ client.onDisconnect ([&client, &disconnected]() {
122179 if (auto lg = client.getLogger ()) {
123180 lg->info (" [App] Disconnected, cleaning up" );
124181 }
125- });
182+ });
126183
127184 // Register handler to log when "chat message" event is received
128- client.on (" chat message" , [&client](const nlohmann::json& data){
185+ client.on (" chat message" , [&client](const nlohmann::json& data) {
129186 if (auto lg = client.getLogger ()) {
130187 lg->info (" [App] chat message received: {}" , data.dump ());
131188 }
132- });
189+ });
133190
134191 // Register handler to log any received event
135- client.onAny ([&client](const std::string& event, const nlohmann::json& data){
192+ client.onAny ([&client](const std::string& event, const nlohmann::json& data) {
136193 if (auto lg = client.getLogger ()) {
137194 lg->info (" [App] any event: {} -> {}" , event, data.dump ());
138195 }
139- });
196+ });
140197
141198 try {
142199 client.connect (" 127.0.0.1" , 3002 , " /socket.io/" );
143- } catch (const std::exception &ex) {
200+ }
201+ catch (const std::exception& ex) {
144202 console->error (" [Example][Error] V2 connect failed: {}" , ex.what ());
145203 return ;
146204 }
147205
148206 // Wait for initial connection (10s)
149207 if (!SioClientBase::waitForConnect (client, 10000 )) {
150208 console->error (" [Example][Error] V2 client did not connect within timeout" );
151- return ;
152- }
209+ return ;
210+ }
153211
154212 // Work loop
155213 for (int i = 0 ; i < 3 ; ++i) {
156214
157215 // Check final connection state before starting work
158216 if (disconnected.load (std::memory_order_relaxed) || !client.isConnected ()) {
159217 console->info (" [Example] Aborting send loop due to disconnect" );
160- return ;
218+ return ;
161219 }
162220
163221 // If connected, send message to server
164- client.emit (" chat message" , nlohmann::json ({{" user" , " cpp_client_v2" }, {" text" , " Hello from v2 client!" }}));
222+ client.emit (" chat message" , nlohmann::json ({ {" user" , " cpp_client_v2" }, {" text" , " Hello from v2 client!" } }));
165223
166224 std::this_thread::sleep_for (std::chrono::seconds (3 ));
167225 }
@@ -171,53 +229,3 @@ static void runV2Example(std::shared_ptr<spdlog::logger> console)
171229 client.stop (); // close socket
172230 console->info (" [Example] Socket.IO v2 example finished" );
173231}
174-
175- int main () {
176-
177- // initialize logging
178- auto console = spdlog::stdout_color_mt (" console" );
179- if (console == nullptr ) {
180- std::cerr << " [Fatal] Failed to create console logger" << std::endl;
181- return 1 ;
182- }
183- spdlog::set_level (spdlog::level::trace);
184- // console->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] %v");
185- // console->set_pattern("[%H:%M:%S.%e] [%^%l%$] %v");
186- spdlog::set_default_logger (console);
187-
188- #ifdef _WIN32
189- // Ensure WinSock is initialized before any socket operations
190- try {
191- WinSockInit wsi;
192- } catch (const std::exception& ex) {
193- console->critical (" [Fatal] WinSock initialization failed: {}" , ex.what ());
194- return 1 ;
195- }
196- #endif
197-
198- std::unique_ptr<CurlGlobal> curlInit = nullptr ;
199- try {
200- curlInit = std::make_unique<CurlGlobal>();
201- // CurlGlobal will automatically clean up when going out of scope at the end of main
202- } catch (const std::exception& ex) {
203- console->critical (" [Fatal] CurlGlobal initialization failed: {}" , ex.what ());
204- return 1 ;
205- }
206-
207- try { // Run examples separately
208-
209- runV4Example (console); // socket.io v3/v4 example with direct websocket connection
210-
211- std::this_thread::sleep_for (std::chrono::seconds (1 ));
212- console->info (" ==============================================" );
213-
214- runV2Example (console); // socket.io v2 example with polling handshake
215-
216- std::this_thread::sleep_for (std::chrono::seconds (2 )); // brief observe period
217- } catch (const std::exception& ex) {
218- console->critical (" [Fatal] {}" , ex.what ());
219- return 2 ;
220- }
221-
222- return 0 ;
223- }
0 commit comments