26 bool start(uint16_t port)
override;
38 void update(uint64_t nbMessagesToProcess,
bool wait)
override;
77 : _acceptor(this->_ioContext)
90 if (this->_acceptor.is_open()) {
91 this->_acceptor.close();
93 asio::ip::tcp::endpoint endpoint(asio::ip::tcp::v4(), port);
94 this->_acceptor.open(endpoint.protocol());
95 this->_acceptor.set_option(asio::ip::tcp::acceptor::reuse_address(
true));
96 this->_acceptor.bind(endpoint);
97 this->_acceptor.listen();
99 this->waitForClientConnections();
100 this->_contextThread = std::thread([
this]() { this->_ioContext.run(); });
102 catch (std::exception &e) {
103 std::cerr <<
"[SERVER] Exception: " << e.what() << std::endl;
107 std::cout <<
"[SERVER] Started on port " << port << std::endl;
114 this->_acceptor.close();
115 this->_ioContext.
stop();
116 if (this->_contextThread.joinable()) {
117 this->_contextThread.join();
119 std::cout <<
"[SERVER] Stopped" << std::endl;
125 if (client && client->isConnected()) {
128 this->onClientDisconnect(client);
130 this->_connections.erase(std::remove(this->_connections.begin(), this->_connections.end(), client),
131 this->_connections.end());
138 bool disconnectedClients =
false;
140 for (
auto &client: this->_connections) {
141 if (client && client->isConnected()) {
144 this->onClientDisconnect(client);
146 disconnectedClients =
true;
149 if (disconnectedClients) {
150 this->_connections.erase(std::remove(this->_connections.begin(), this->_connections.end(),
nullptr),
151 this->_connections.end());
159 using namespace std::chrono_literals;
160 this->_messagesIn.waitFor(1s);
163 uint64_t processedMessages = 0;
165 while (processedMessages < nbMessagesToProcess && !this->_messagesIn.empty()) {
166 auto msg = this->_messagesIn.popFront();
168 this->onMessage(msg.remote, msg.msg);
173 bool disconnectedClients =
false;
175 for (
auto &client: this->_connections) {
176 if (!(client && client->isConnected())) {
177 this->onClientDisconnect(client);
179 disconnectedClients =
true;
182 if (disconnectedClients) {
183 this->_connections.erase(std::remove(this->_connections.begin(), this->_connections.end(),
nullptr),
184 this->_connections.end());
197 std::cout <<
"onDisconnect client id: " << client->getId() << std::endl;
206 std::cout <<
"from client id: " << client->getId() <<
" received: '" << str <<
"'" << std::endl;
212 this->_acceptor.async_accept(
213 [
this](std::error_code ec, asio::ip::tcp::socket socket) {
215 std::cout <<
"[SERVER] New Connection: " << socket.remote_endpoint() << std::endl;
217 std::shared_ptr<AsioTCPConnection<T>> newConnection = std::make_shared<AsioTCPConnection<T>>(
218 this->_ioContext, std::move(socket));
220 newConnection->setId(this->_idCounter++);
221 if (this->onClientConnect(newConnection)) {
222 newConnection->setCallbackOnMessage([
this, newConnection](
Message<T> msg) {
225 this->_connections.push_back(std::move(newConnection));
226 this->_connections.back()->readForMessages();
228 std::cout <<
"[" << this->_connections.back()->getId() <<
"] Connection Approved" << std::endl;
230 std::cout <<
"[-----] Connection Denied" << std::endl;
233 std::cout <<
"[SERVER] New Connection Error: " << ec.message() << std::endl;
235 this->waitForClientConnections();