Skip to content

Commit 466657e

Browse files
committed
update code
1 parent 0b4cf87 commit 466657e

3 files changed

Lines changed: 90 additions & 94 deletions

File tree

ix/CMakeLists.txt

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.26)
22

33
project(socketio_client_example LANGUAGES CXX)
44

5+
set(EXE_NAME "socketio_client")
6+
57
set(CMAKE_CXX_STANDARD 17)
68
set(CMAKE_CXX_STANDARD_REQUIRED ON)
79
set(CMAKE_CXX_EXTENSIONS OFF)
@@ -17,21 +19,9 @@ find_package(spdlog REQUIRED) # spdlog https://githunb.com/gabime/spdlog
1719
find_package(nlohmann_json REQUIRED) # nlohmann json https://github.com/nlohmann/json
1820
find_package(ixwebsocket REQUIRED) # ixwebsocket https://github.com/machinezone/IXWebSocket
1921

20-
#find_package(ixwebsocket QUIET)
21-
# Try to find ixwebsocket; if not available, fetch it
22-
# if(NOT ixwebsocket_FOUND)
23-
# include(FetchContent)
24-
# FetchContent_Declare(
25-
# ixwebsocket
26-
# GIT_REPOSITORY https://github.com/machinezone/IXWebSocket.git
27-
# GIT_TAG v11.2.0
28-
# )
29-
# FetchContent_MakeAvailable(ixwebsocket)
30-
# endif()
31-
32-
add_executable(socketio_client main.cpp)
22+
add_executable(${EXE_NAME} main.cpp)
3323

34-
target_link_libraries(socketio_client PRIVATE
24+
target_link_libraries(${EXE_NAME} PRIVATE
3525
spdlog::spdlog
3626
nlohmann_json::nlohmann_json
3727
CURL::libcurl
@@ -41,7 +31,7 @@ target_link_libraries(socketio_client PRIVATE
4131

4232
if(WIN32)
4333
# required for Winsock and BCryptGenRandom used by mbedtls (mbedcrypto)
44-
target_link_libraries(socketio_client PRIVATE ws2_32 bcrypt)
34+
target_link_libraries(${EXE_NAME} PRIVATE ws2_32 bcrypt)
4535
# ws2_32 is winsock, required for Windows socket programming
4636
# bcrypt is required for mbedtls's random number generation on Windows
4737
endif()
@@ -50,7 +40,7 @@ endif()
5040
if(MSVC)
5141
# Use /W4 for maximum warnings and /permissive- to disable non-standard extensions
5242
# This ensures that we get the most out of the compiler's warning system while maintaining compatibility with standard C++.
53-
target_compile_options(socketio_client PRIVATE /W4 /permissive-)
43+
target_compile_options(${EXE_NAME} PRIVATE /W4 /permissive-)
5444
foreach(var
5545
CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
5646
CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS_MINSIZEREL
@@ -62,5 +52,5 @@ if(MSVC)
6252
endif()
6353
endforeach()
6454
else()
65-
target_compile_options(socketio_client PRIVATE -Wall -Wextra -Wpedantic)
55+
target_compile_options(${EXE_NAME} PRIVATE -Wall -Wextra -Wpedantic)
6656
endif()

ix/SioClientBase.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020

2121
#include <nlohmann/json.hpp> // json parsing for event data and payloads
2222

23-
#include "WinSockInit.hpp" // winsock initialization on Windows
24-
2523
// Base client with common logic
2624
class SioClientBase {
2725
public:

ix/main.cpp

Lines changed: 83 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,71 @@
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

Comments
 (0)