Files
pip/libs/client_server/piclient_server_server.cpp
2024-09-11 15:44:02 +03:00

113 lines
2.8 KiB
C++

/*
PIP - Platform Independent Primitives
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "piclient_server_server.h"
#include "piclient_server_client.h"
#include "piethernet.h"
#include "piliterals_time.h"
PIClientServer::Server::Server() {
tcp_server = new PIEthernet(PIEthernet::TCP_Server);
clean_thread = new PIThread();
client_factory = [] { return new Client(); };
CONNECTL(tcp_server, newConnection, [this](PIEthernet * c) {
PIMutexLocker guard(clients_mutex);
if (clients.size_s() >= max_clients) {
piCout << "Server::newConnection overflow clients count";
delete c;
return;
}
auto sc = client_factory();
if (!sc) {
piCout << "ClientFactory returns nullptr!";
return;
}
sc->createForServer(c);
newClient(sc);
});
clean_thread->start(
[this]() {
PIVector<Client *> to_delete;
clients_mutex.lock();
for (auto c: clients) {
const PIEthernet * eth = c->getTCP();
if (!eth) continue;
if (eth->isConnected()) continue;
c->can_write = false;
to_delete << c;
}
for (auto c: to_delete)
clients.removeOne(c);
clients_mutex.unlock();
for (auto c: to_delete) {
c->destroy();
delete c;
}
},
5_Hz);
}
PIClientServer::Server::~Server() {
clean_thread->stopAndWait();
piDeleteSafety(clean_thread);
stopServer();
for (auto c: clients) {
c->destroy();
delete c;
}
piDeleteSafety(tcp_server);
}
void PIClientServer::Server::listen(PINetworkAddress addr) {
if (!tcp_server) return;
stopServer();
tcp_server->listen(addr, true);
// piCout << "Listen on" << addr.toString();
}
void PIClientServer::Server::setMaxClients(int new_max_clients) {
max_clients = new_max_clients;
}
void PIClientServer::Server::enableSymmetricEncryption(const PIByteArray & key) {
crypt_key = key;
}
void PIClientServer::Server::stopServer() {
if (!tcp_server) return;
tcp_server->stopAndWait();
}
void PIClientServer::Server::newClient(Client * c) {
clients << c;
c->enableSymmetricEncryption(crypt_key);
c->readed_func = [this, c](PIByteArray ba) { readed(c, ba); };
c->tcp->startThreadedRead();
c->connected();
piCout << "New client";
}