6#include <unordered_map>
7#include <unordered_set>
17template <
typename SessionType = EmptySession>
23template <
typename SessionType>
41 void join(
const std::string& room);
46 void leave(
const std::string& room);
51 auto to(
const std::string& room);
58 const std::string&
id()
const {
return id_; }
68 std::unordered_set<std::string> rooms_;
76template <
typename SessionType>
79 using SocketPtr = std::shared_ptr<EventSocket<SessionType>>;
87 template <
typename PayloadType>
93 }
catch (
const std::exception& e) {
95 std::cerr <<
"[EventRouter] Invalid payload for event '" <<
event <<
"': " << e.what() <<
"\n";
113 on_connect_ = std::move(handler);
120 on_disconnect_ = std::move(handler);
130 static std::atomic<uint64_t>
counter = 0;
131 std::string
id =
"ws_" + std::to_string(++
counter) +
"_" + std::to_string(
reinterpret_cast<uint64_t>(&
raw_ws));
133 auto es = std::make_shared<EventSocket<SessionType>>(
raw_ws, *
this, id);
136 std::lock_guard<std::mutex>
lock(mutex_);
140 if (on_connect_) on_connect_(*
es);
142 raw_ws.on_message([
this,
id](
const std::string&
msg) {
145 if (!
j.contains(
"event"))
return;
150 auto socket = get_socket(
id);
153 if (
it != handlers_.end()) {
162 raw_ws.on_close([
this,
id]() {
163 auto socket = get_socket(
id);
166 std::lock_guard<std::mutex>
lock(mutex_);
168 for (
const auto& room :
socket->rooms_) {
169 rooms_[room].erase(
id);
182 template <
typename T>
195 void join_room(
const std::string&
id,
const std::string& room) {
196 std::lock_guard<std::mutex>
lock(mutex_);
197 if (sockets_.count(
id)) {
198 sockets_[id]->rooms_.insert(room);
199 rooms_[room].insert(
id);
203 void leave_room(
const std::string&
id,
const std::string& room) {
204 std::lock_guard<std::mutex>
lock(mutex_);
205 if (sockets_.count(
id)) {
206 sockets_[id]->rooms_.erase(room);
207 rooms_[room].erase(
id);
212 std::lock_guard<std::mutex>
lock(mutex_);
213 if (rooms_.count(room)) {
214 for (
const std::string&
id : rooms_[room]) {
215 if (sockets_.count(
id)) {
216 sockets_[id]->raw().send(
msg);
223 SocketPtr get_socket(
const std::string&
id) {
224 std::lock_guard<std::mutex>
lock(mutex_);
225 auto it = sockets_.find(
id);
226 if (
it != sockets_.end())
return it->second;
231 std::unordered_map<std::string, SocketPtr> sockets_;
232 std::unordered_map<std::string, std::unordered_set<std::string>> rooms_;
233 std::unordered_map<std::string, std::function<void(EventSocket<SessionType>&,
const nlohmann::json&)>> handlers_;
235 std::function<void(EventSocket<SessionType>&)> on_connect_;
236 std::function<void(EventSocket<SessionType>&)> on_disconnect_;
239template <
typename SessionType>
241 router_.join_room(id_, room);
244template <
typename SessionType>
246 router_.leave_room(id_, room);
249template <
typename SessionType>
251 return router_.to(room);
Represents an active WebSocket connection.
Definition WebSocketConnection.hpp:56
void send(const std::string &message)
Sends a text message over the WebSocket connection.
Definition WebSocketConnection.cpp:113
a class to store JSON values
Definition json.hpp:19401
static basic_json parse(InputType &&i, const parser_callback_t cb=nullptr, const bool allow_exceptions=true, const bool ignore_comments=false)
deserialize from a compatible input
Definition json.hpp:23317
The main application class for the Orbit Framework.
Definition App.hpp:26
A Socket.IO style event router for WebSockets with Room and Session support.
Definition EventRouter.hpp:77
void join_room(const std::string &id, const std::string &room)
Definition EventRouter.hpp:195
std::shared_ptr< EventSocket< SessionType > > SocketPtr
Definition EventRouter.hpp:79
void on(const std::string &event, std::function< void(EventSocket< SessionType > &)> handler)
Registers an untyped event handler (no data expected).
Definition EventRouter.hpp:103
void on(const std::string &event, std::function< void(EventSocket< SessionType > &, const PayloadType &)> handler)
Definition EventRouter.hpp:88
void leave_room(const std::string &id, const std::string &room)
Definition EventRouter.hpp:203
void on_connect(std::function< void(EventSocket< SessionType > &)> handler)
Registers a connection handler.
Definition EventRouter.hpp:112
void on_disconnect(std::function< void(EventSocket< SessionType > &)> handler)
Registers a disconnection handler.
Definition EventRouter.hpp:119
RoomBroadcaster to(const std::string &room)
Definition EventRouter.hpp:190
void attach(server::App &app, const std::string &path)
Attaches this EventRouter to the Orbit App at a specific path.
Definition EventRouter.hpp:126
void broadcast_to_room(const std::string &room, const std::string &msg)
Definition EventRouter.hpp:211
Represents a connected client in the EventRouter.
Definition EventRouter.hpp:24
void join(const std::string &room)
Joins a specific room/channel.
Definition EventRouter.hpp:240
void leave(const std::string &room)
Leaves a specific room/channel.
Definition EventRouter.hpp:245
void emit(const std::string &event, const T &data)
Emits an event with strongly-typed data back to this specific client.
Definition EventRouter.hpp:33
EventSocket(http::websocket::WebSocketConnection &raw, EventRouter< SessionType > &router, std::string id)
Definition EventRouter.hpp:26
auto to(const std::string &room)
Returns a broadcaster to emit messages to everyone in the room.
Definition EventRouter.hpp:250
const std::string & id() const
Definition EventRouter.hpp:58
SessionType & session()
The strongly-typed session state attached to this connection.
Definition EventRouter.hpp:56
http::websocket::WebSocketConnection & raw()
Definition EventRouter.hpp:61
basic_json<> json
default specialization
Definition json.hpp:3422
Definition EventRouter.hpp:13
Definition EventRouter.hpp:15
Definition EventRouter.hpp:178
EventRouter & router
Definition EventRouter.hpp:179
void emit(const std::string &event, const T &data)
Definition EventRouter.hpp:183
std::string room
Definition EventRouter.hpp:180