|
| 1 | +/* |
| 2 | +** EPITECH PROJECT, 2024 |
| 3 | +** server_tcp.cpp |
| 4 | +** File description: |
| 5 | +** ServerTCP class |
| 6 | +*/ |
| 7 | + |
| 8 | +#include "./server_websocket.hpp" |
| 9 | + |
| 10 | +#include <iostream> |
| 11 | + |
| 12 | +using namespace abra::server; |
| 13 | +using namespace boost::asio; |
| 14 | + |
| 15 | +ServerWebsocket::ServerWebsocket( |
| 16 | + const int &port, |
| 17 | + const std::function<void(std::pair<std::uint64_t, const boost::json::object &>)> &handler) |
| 18 | + : acceptor_(ioc_, ip::tcp::endpoint(ip::tcp::v4(), port)), |
| 19 | + lastClientId_(0), |
| 20 | + handler_(handler), |
| 21 | + logger_("websocket") {} |
| 22 | + |
| 23 | +ServerWebsocket::~ServerWebsocket() { |
| 24 | + this->Close(); |
| 25 | +} |
| 26 | + |
| 27 | +void ServerWebsocket::Start() { |
| 28 | + AcceptNewConnection(); |
| 29 | + |
| 30 | + logger_.Info("Websocket started on port " + std::to_string(acceptor_.local_endpoint().port())); |
| 31 | + ioc_.run(); |
| 32 | +} |
| 33 | + |
| 34 | +void ServerWebsocket::AcceptNewConnection() { |
| 35 | + acceptor_.async_accept([this](boost::system::error_code error, ip::tcp::socket socket) { |
| 36 | + if (!error) { |
| 37 | + std::uint64_t clientId = lastClientId_; |
| 38 | + lastClientId_++; |
| 39 | + |
| 40 | + logger_.Info("New connection accepted"); |
| 41 | + auto clientSession = std::make_shared<SessionWebsocket>( |
| 42 | + std::move(socket), clientId, handler_, |
| 43 | + [this](std::uint64_t clientId) { this->OnSessionClose(clientId); }); |
| 44 | + |
| 45 | + clientSession->Start(); |
| 46 | + logger_.Info("Session started with clientID " + std::to_string(clientId)); |
| 47 | + |
| 48 | + RegisterNewClient(clientSession, clientId); |
| 49 | + } else { |
| 50 | + logger_.Error("Error while accepting new connection: " + error.message()); |
| 51 | + } |
| 52 | + |
| 53 | + AcceptNewConnection(); |
| 54 | + }); |
| 55 | +} |
| 56 | + |
| 57 | +void ServerWebsocket::RegisterNewClient(std::shared_ptr<SessionWebsocket> client, |
| 58 | + const std::uint64_t &clientId) { |
| 59 | + clients_[clientId] = std::move(client); |
| 60 | +} |
| 61 | + |
| 62 | +void ServerWebsocket::Close() { |
| 63 | + if (!acceptor_.is_open() || ioc_.stopped()) { |
| 64 | + return; |
| 65 | + } |
| 66 | + |
| 67 | + this->logger_.Info("Closing session"); |
| 68 | + |
| 69 | + for (auto &client : clients_) { |
| 70 | + client.second->Close(); |
| 71 | + } |
| 72 | + ioc_.stop(); |
| 73 | + |
| 74 | + this->logger_.Info("Session closed"); |
| 75 | +} |
| 76 | + |
| 77 | +void ServerWebsocket::SendToClient(const std::uint64_t &clientId, |
| 78 | + const boost::json::object &message) { |
| 79 | + if (clients_.find(clientId) == clients_.end() || !clients_[clientId]) { |
| 80 | + logger_.Error("Client not found"); |
| 81 | + return; |
| 82 | + } |
| 83 | + |
| 84 | + clients_[clientId]->Send(message); |
| 85 | +} |
| 86 | + |
| 87 | +void ServerWebsocket::OnSessionClose(const std::uint64_t &clientId) { |
| 88 | + if (clients_.find(clientId) == clients_.end()) { |
| 89 | + logger_.Error("Client not found"); |
| 90 | + return; |
| 91 | + } |
| 92 | + |
| 93 | + clients_.erase(clientId); |
| 94 | + logger_.Info("Client " + std::to_string(clientId) + " disconnected"); |
| 95 | +} |
0 commit comments