Network System 0.1.1
High-performance modular networking library for scalable client-server applications
Loading...
Searching...
No Matches
websocket_chat.cpp File Reference

WebSocket chat server and client in a single program. More...

#include <kcenon/network/facade/websocket_facade.h>
#include <kcenon/network/interfaces/i_session.h>
#include <atomic>
#include <chrono>
#include <iostream>
#include <map>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
Include dependency graph for websocket_chat.cpp:

Go to the source code of this file.

Functions

void run_server ()
 Run a WebSocket chat server that broadcasts messages to all clients.
 
void run_client (const std::string &name, const std::vector< std::string > &messages)
 Run a WebSocket chat client that sends messages.
 
int main ()
 

Variables

static std::atomic< bool > g_server_ready {false}
 
static std::atomic< bool > g_done {false}
 

Detailed Description

WebSocket chat server and client in a single program.

Definition in file websocket_chat.cpp.

Function Documentation

◆ main()

int main ( )

Definition at line 175 of file websocket_chat.cpp.

175 {
176 std::cout << "=== WebSocket Chat Example ===" << std::endl;
177
178 try {
179 // Start server
180 std::thread server_thread(run_server);
181
182 // Start two clients with different messages
183 std::thread client1(run_client, "Alice",
184 std::vector<std::string>{"Hello everyone!", "How are you?"});
185 std::thread client2(run_client, "Bob",
186 std::vector<std::string>{"Hi Alice!", "I am fine, thanks!"});
187
188 // Wait for clients to finish
189 client1.join();
190 client2.join();
191
192 // Signal server to stop
193 g_done.store(true);
194 server_thread.join();
195
196 std::cout << "\n=== Chat example completed ===" << std::endl;
197 } catch (const std::exception& e) {
198 std::cerr << "Exception: " << e.what() << std::endl;
199 return 1;
200 }
201
202 return 0;
203}
void run_client()
Definition udp_echo.cpp:109
void run_server()
Run a WebSocket chat server that broadcasts messages to all clients.
static std::atomic< bool > g_done

References g_done, run_client(), and run_server().

Here is the call graph for this function:

◆ run_client()

void run_client ( const std::string & name,
const std::vector< std::string > & messages )

Run a WebSocket chat client that sends messages.

Definition at line 128 of file websocket_chat.cpp.

128 {
129 // Wait for server to be ready
130 while (!g_server_ready.load()) {
131 std::this_thread::sleep_for(std::chrono::milliseconds(50));
132 }
133 std::this_thread::sleep_for(std::chrono::milliseconds(200));
134
136 auto client = ws.create_client({
137 .client_id = name,
138 });
139
140 // Print received broadcast messages
141 client->set_receive_callback([&name](const std::vector<uint8_t>& data) {
142 std::string msg(data.begin(), data.end());
143 std::cout << " [" << name << " received] " << msg << std::endl;
144 });
145
146 client->set_error_callback([&name](std::error_code ec) {
147 std::cerr << " [" << name << "] Error: " << ec.message() << std::endl;
148 });
149
150 // Connect to the chat server
151 auto connect_result = client->start("127.0.0.1", 9001);
152 if (connect_result.is_err()) {
153 std::cerr << " [" << name << "] Connection failed: "
154 << connect_result.error().message << std::endl;
155 return;
156 }
157
158 std::this_thread::sleep_for(std::chrono::milliseconds(200));
159
160 // Send messages with delays
161 for (const auto& msg : messages) {
162 std::vector<uint8_t> data(msg.begin(), msg.end());
163 auto send_result = client->send(std::move(data));
164 if (send_result.is_err()) {
165 std::cerr << " [" << name << "] Send failed: "
166 << send_result.error().message << std::endl;
167 }
168 std::this_thread::sleep_for(std::chrono::milliseconds(600));
169 }
170
171 std::this_thread::sleep_for(std::chrono::milliseconds(500));
172 client->stop();
173}
Simplified facade for creating WebSocket clients and servers.
auto create_client(const client_config &config) const -> Result< std::shared_ptr< interfaces::i_protocol_client > >
Creates a WebSocket client with the specified configuration.
static std::atomic< bool > g_server_ready

References kcenon::network::facade::websocket_facade::create_client(), and g_server_ready.

Here is the call graph for this function:

◆ run_server()

void run_server ( )

Run a WebSocket chat server that broadcasts messages to all clients.

Definition at line 52 of file websocket_chat.cpp.

52 {
54 constexpr uint16_t port = 9001;
55
56 auto server = ws.create_server({
57 .port = port,
58 .path = "/chat",
59 .server_id = "ChatServer",
60 });
61
62 // Track connected sessions
63 std::mutex sessions_mutex;
64 std::map<std::string, std::shared_ptr<interfaces::i_session>> sessions;
65
66 server->set_connection_callback(
67 [&sessions, &sessions_mutex](std::shared_ptr<interfaces::i_session> session) {
68 std::lock_guard<std::mutex> lock(sessions_mutex);
69 std::string id(session->id());
70 sessions[id] = session;
71 std::cout << "[Server] User joined: " << id << " ("
72 << sessions.size() << " online)" << std::endl;
73 });
74
75 server->set_disconnection_callback(
76 [&sessions, &sessions_mutex](std::string_view session_id) {
77 std::lock_guard<std::mutex> lock(sessions_mutex);
78 sessions.erase(std::string(session_id));
79 std::cout << "[Server] User left: " << session_id << " ("
80 << sessions.size() << " online)" << std::endl;
81 });
82
83 // Broadcast received messages to all connected clients
84 server->set_receive_callback(
85 [&sessions, &sessions_mutex](std::string_view sender_id,
86 const std::vector<uint8_t>& data) {
87 std::string message(data.begin(), data.end());
88 std::cout << "[Server] " << sender_id << " says: " << message << std::endl;
89
90 // Broadcast to all sessions
91 std::string broadcast = std::string(sender_id) + ": " + message;
92 std::vector<uint8_t> broadcast_data(broadcast.begin(), broadcast.end());
93
94 std::lock_guard<std::mutex> lock(sessions_mutex);
95 for (auto& [id, session] : sessions) {
96 session->send(std::vector<uint8_t>(broadcast_data));
97 }
98 });
99
100 server->set_error_callback(
101 [](std::string_view session_id, std::error_code ec) {
102 std::cerr << "[Server] Error on " << session_id << ": " << ec.message()
103 << std::endl;
104 });
105
106 auto result = server->start(port);
107 if (result.is_err()) {
108 std::cerr << "[Server] Failed to start: " << result.error().message << std::endl;
109 return;
110 }
111
112 std::cout << "[Server] Chat server running on ws://localhost:" << port << "/chat"
113 << std::endl;
114 g_server_ready.store(true);
115
116 // Wait until chat is done
117 while (!g_done.load()) {
118 std::this_thread::sleep_for(std::chrono::milliseconds(100));
119 }
120
121 server->stop();
122 std::cout << "[Server] Stopped." << std::endl;
123}
auto create_server(const server_config &config) const -> Result< std::shared_ptr< interfaces::i_protocol_server > >
Creates a WebSocket server with the specified configuration.
@ server
Server-side handling of a request.

References kcenon::network::facade::websocket_facade::create_server(), g_done, g_server_ready, and kcenon::network::message.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ g_done

std::atomic<bool> g_done {false}
static

Definition at line 47 of file websocket_chat.cpp.

47{false};

Referenced by main(), and run_server().

◆ g_server_ready

std::atomic<bool> g_server_ready {false}
static
Examples
websocket_chat.cpp.

Definition at line 46 of file websocket_chat.cpp.

46{false};

Referenced by run_client(), and run_server().