5#include <nlohmann/json.hpp>
10using json = nlohmann::json;
11using Clock = std::chrono::steady_clock;
14 network_manager(parent)
25 rtc::WebSocketServerConfiguration cfg;
26 cfg.bindAddress =
"0.0.0.0";
28 cfg.connectionTimeout = std::chrono::milliseconds(0);
30 server = std::make_shared<rtc::WebSocketServer>(cfg);
32 server->onClient([
this](std::shared_ptr<rtc::WebSocket> ws)
34 auto addrOpt = ws->remoteAddress();
35 if (!addrOpt) { std::cout <<
"[SignalingServer] Client connected (no addr)\n";
return; }
36 std::string clientId = *addrOpt;
37 std::cout <<
"[SignalingServer] Client Connected: " << clientId <<
"\n";
41 ws->onMessage([
this, clientId](std::variant<rtc::binary, rtc::string>
msg) {
42 std::cout <<
"[SignalingServer] MESSAGE RECEIVED" <<
"\n";
43 if (!std::holds_alternative<rtc::string>(
msg))
return;
44 const auto& s = std::get<rtc::string>(
msg);
45 std::cout <<
"[SignalingServer] MESSAGE: " << s <<
"\n";
50 ws->onError([clientId](std::string err) {
51 std::cout <<
"[SignalingServer] Client Error (" << clientId <<
"): " << err <<
"\n";
54 ws->onClosed([
this, clientId]() {
55 std::cout <<
"[SignalingServer] Client disconnected: " << clientId <<
"\n";
62 std::cout <<
"[SignalingServer] Listening at ws://0.0.0.0:" << port <<
"\n";
98 j = json::parse(text);
113 throw std::runtime_error(
"NetworkManager expired");
116 const std::string expected = nm->getNetworkPassword();
118 const bool ok = (expected.empty() || provided == expected);
119 const std::string username = j.value(std::string(
msg::key::Username),
"guest" + clientId);
126 std::vector<std::string> others;
130 others.emplace_back(
id);
133 const std::string gmUniqueId = nm->getMyUniqueId();
141 sendTo(clientId, resp.dump());
147 sendTo(clientId, resp.dump());
152 it2->second->close();
161 clientId,
"guest" + clientId);
162 sendTo(clientId, resp.dump());
177 const std::string dump = j.dump();
180 if (ws && !ws->isClosed())
196 const std::string dump = j.dump();
201 if (ws && !ws->isClosed())
212 if (it !=
authClients_.end() && it->second && !it->second->isClosed())
214 it->second->send(j.dump());
222 it->second->send(message);
227 it->second->send(message);
235 if (ws && !ws->isClosed())
254 auto closer = [](
auto& map)
256 for (
auto& [
id, ws] : map)
263 ws->onMessage(
nullptr);
264 ws->onClosed(
nullptr);
265 ws->onError(
nullptr);
288 std::cout <<
"[SignalingServer] Authenticated: " << clientId <<
"\n";
301 if (!it->second->isClosed())
std::chrono::steady_clock Clock
static Logger & instance()
static void safeCloseWebSocket(std::shared_ptr< rtc::WebSocket > &ws)
std::shared_ptr< rtc::WebSocketServer > server
void onMessage(const std::string &clientId, const std::string &text)
SignalingServer(std::weak_ptr< NetworkManager > parent)
void broadcast(const std::string &message)
bool isAuthenticated(const std::string &clientId) const
void disconnectClient(const std::string &clientId)
std::unordered_map< std::string, std::shared_ptr< rtc::WebSocket > > pendingClients_
void onConnect(std::string clientId, std::shared_ptr< rtc::WebSocket > client)
void disconnectAllClients()
void moveToAuthenticated(const std::string &clientId)
void start(unsigned short port)
std::weak_ptr< NetworkManager > network_manager
std::unordered_map< std::string, std::shared_ptr< rtc::WebSocket > > authClients_
void sendTo(const std::string &clientId, const std::string &message)
constexpr std::string_view AuthToken
constexpr std::string_view Type
constexpr std::string_view Target
constexpr std::string_view To
constexpr std::string_view UniqueId
constexpr std::string_view From
constexpr std::string_view Username
constexpr std::string_view Broadcast
constexpr std::string_view PeerDisconnect
constexpr std::string_view Auth
constexpr std::string False
constexpr std::string True
Json makeBroadcastShutdown()
nlohmann::json makeAuthResponse(const std::string ok, const std::string &msg, const std::string &clientId, const std::string &username, const std::vector< std::string > &clients={}, const std::string &gmPeerId="", const std::string &uniqueId="")