code format

This commit is contained in:
2022-12-14 14:13:52 +03:00
parent 430a41fefc
commit c2b8a8d6da
297 changed files with 27331 additions and 24162 deletions

View File

@@ -1,22 +1,22 @@
#include "cloudserver.h"
CloudServer::CloudServer(DispatcherClient * c, const PIByteArray & sname) : server(c) {
CloudServer::CloudServer(DispatcherClient * c, const PIByteArray & sname): server(c) {
setName(sname.toHex());
server_uuid = sname;
CONNECTL(c, dataReadedServer, ([this](uint id, PIByteArray & ba){
last_ping.reset();
mutex_clients.lock();
DispatcherClient * cl = index_clients.value(id, nullptr);
mutex_clients.unlock();
if (cl) cl->sendData(ba);
}));
CONNECTL(c, pingReceived, [this]() {last_ping.reset();});
CONNECTL(c, dataReadedServer, ([this](uint id, PIByteArray & ba) {
last_ping.reset();
mutex_clients.lock();
DispatcherClient * cl = index_clients.value(id, nullptr);
mutex_clients.unlock();
if (cl) cl->sendData(ba);
}));
CONNECTL(c, pingReceived, [this]() { last_ping.reset(); });
last_ping.reset();
}
CloudServer::~CloudServer() {
for (auto c :clients) {
for (auto c: clients) {
c->close();
}
}
@@ -36,10 +36,10 @@ void CloudServer::addClient(DispatcherClient * c) {
mutex_clients.unlock();
c->sendConnected(1);
server->sendConnected(cid);
CONNECTL(c, dataReaded, ([this, cid](PIByteArray & ba){
// piCoutObj << c->clientId() << "dataReaded";
server->sendDataToClient(ba, cid);
}));
CONNECTL(c, dataReaded, ([this, cid](PIByteArray & ba) {
// piCoutObj << c->clientId() << "dataReaded";
server->sendDataToClient(ba, cid);
}));
}
@@ -68,11 +68,10 @@ double CloudServer::lastPing() {
void CloudServer::printStatus() {
mutex_clients.lock();
piCout << " " << "Clients for" << server->address() << server_uuid.toHex() << ":";
piCout << " "
<< "Clients for" << server->address() << server_uuid.toHex() << ":";
for (auto c: clients) {
piCout << " " << c->address() << c->clientId();
}
mutex_clients.unlock();
}

View File

@@ -4,23 +4,24 @@
#include "dispatcherclient.h"
class CloudServer : public PIObject {
class CloudServer: public PIObject {
PIOBJECT(CloudServer)
public:
CloudServer(DispatcherClient * c, const PIByteArray & sname);
~CloudServer();
PIByteArray serverUUID() const;
void addClient(DispatcherClient * c);
void removeClient(DispatcherClient * c);
PIVector<DispatcherClient*> getClients();
PIVector<DispatcherClient *> getClients();
EVENT_HANDLER0(void, printStatus);
const DispatcherClient * getConnection() const {return server;}
const DispatcherClient * getConnection() const { return server; }
double lastPing();
private:
DispatcherClient * server;
PIVector<DispatcherClient*> clients;
PIMap<uint, DispatcherClient*> index_clients;
PIVector<DispatcherClient *> clients;
PIMap<uint, DispatcherClient *> index_clients;
PIByteArray server_uuid;
PITimeMeasurer last_ping;
PIMutex mutex_clients;

View File

@@ -1,8 +1,14 @@
#include "dispatcherclient.h"
#include "picloudtcp.h"
DispatcherClient::DispatcherClient(PIEthernet * eth_, int id) : authorised(false), eth(eth_), streampacker(eth_), tcp(&streampacker), client_id(id) {
DispatcherClient::DispatcherClient(PIEthernet * eth_, int id)
: authorised(false)
, eth(eth_)
, streampacker(eth_)
, tcp(&streampacker)
, client_id(id) {
eth->setName(PIString::fromNumber(id));
CONNECTU(&streampacker, packetReceiveEvent, this, readed);
CONNECTU(eth, disconnected, this, disconnected);
@@ -43,14 +49,18 @@ void DispatcherClient::sendDisconnected(uint client_id) {
void DispatcherClient::sendData(const PIByteArray & data) {
if (tcp.role() == PICloud::TCP::Client) tcp.sendData(data);
else piCoutObj << "error sendData, invalid role";
if (tcp.role() == PICloud::TCP::Client)
tcp.sendData(data);
else
piCoutObj << "error sendData, invalid role";
}
void DispatcherClient::sendDataToClient(const PIByteArray & data, uint client_id) {
if (tcp.role() == PICloud::TCP::Server) tcp.sendData(data, client_id);
else piCoutObj << "error sendDataToClient, invalid role";
if (tcp.role() == PICloud::TCP::Server)
tcp.sendData(data, client_id);
else
piCoutObj << "error sendDataToClient, invalid role";
}
@@ -67,7 +77,7 @@ void DispatcherClient::disconnected(bool withError) {
void DispatcherClient::readed(PIByteArray & ba) {
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
// piCoutObj << "readed" << hdr.first << hdr.second;
// piCoutObj << "readed" << hdr.first << hdr.second;
if (hdr.first == PICloud::TCP::InvalidType) {
piCoutObj << "invalid message";
disconnected(true);
@@ -76,34 +86,35 @@ void DispatcherClient::readed(PIByteArray & ba) {
if (authorised) {
if (hdr.second == tcp.role()) {
switch (hdr.first) {
case PICloud::TCP::Connect:
piCoutObj << "PICloud::TCP::Connect";
return;
case PICloud::TCP::Connect: piCoutObj << "PICloud::TCP::Connect"; return;
case PICloud::TCP::Disconnect:
piCoutObj << "PICloud::TCP::Disconnect";
disconnected(false);
return;
return;
case PICloud::TCP::Data:
//piCoutObj << "TCP::Data" << tcp.role();
// piCoutObj << "TCP::Data" << tcp.role();
if (tcp.role() == PICloud::TCP::Client) {
if (tcp.canParseData(ba)) dataReaded(ba);
else piCoutObj << "invalid data from client";
if (tcp.canParseData(ba))
dataReaded(ba);
else
piCoutObj << "invalid data from client";
}
if (tcp.role() == PICloud::TCP::Server) {
PIPair<uint, PIByteArray> dp = tcp.parseDataServer(ba);
if (!dp.second.isEmpty()) dataReadedServer(dp.first, dp.second);
else piCoutObj << "invalid data from server";
if (!dp.second.isEmpty())
dataReadedServer(dp.first, dp.second);
else
piCoutObj << "invalid data from server";
}
return;
case PICloud::TCP::Ping:
pingReceived();
return;
case PICloud::TCP::Ping: pingReceived(); return;
default:
piCoutObj << "unknown data";
//disconnected(true);
return;
// disconnected(true);
return;
}
} else piCoutObj << "invalid role";
} else
piCoutObj << "invalid role";
} else {
switch (hdr.first) {
case PICloud::TCP::Connect: {
@@ -116,12 +127,11 @@ void DispatcherClient::readed(PIByteArray & ba) {
case PICloud::TCP::Disconnect:
piCoutObj << "unauthorised PICloud::TCP::Disconnect";
disconnected(false);
return;
return;
default:
piCoutObj << "authorised invalid message";
disconnected(true);
return;
return;
}
}
}

View File

@@ -1,13 +1,14 @@
#ifndef DISPATCHERCLIENT_H
#define DISPATCHERCLIENT_H
#include "piethernet.h"
#include "picloudtcp.h"
#include "piethernet.h"
#include "pistreampacker.h"
class DispatcherClient: public PIObject {
PIOBJECT(DispatcherClient)
public:
DispatcherClient(PIEthernet * eth_, int id);
~DispatcherClient();
@@ -18,10 +19,10 @@ public:
void sendData(const PIByteArray & data);
void sendDataToClient(const PIByteArray & data, uint client_id);
void authorise(bool ok);
bool isAuthorised() const {return authorised;}
PICloud::TCP::Role role() const {return tcp.role();}
bool isAuthorised() const { return authorised; }
PICloud::TCP::Role role() const { return tcp.role(); }
PIString address();
uint clientId() const {return client_id;}
uint clientId() const { return client_id; }
EVENT1(disconnectEvent, DispatcherClient *, client)
EVENT2(registerServer, const PIByteArray &, sname, DispatcherClient *, client)
EVENT2(registerClient, const PIByteArray &, sname, DispatcherClient *, client)

View File

@@ -1,13 +1,14 @@
#include "dispatcherserver.h"
#include "piscreentiles.h"
DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::TCP_Server) {
client_gid = 0;
DispatcherServer::DispatcherServer(PIEthernet::Address addr): eth(PIEthernet::TCP_Server) {
client_gid = 0;
max_connections = 1000;
eth.setParameter(PIEthernet::ReuseAddress);
eth.setReadAddress(addr);
// eth.setDebug(false);
// eth.setDebug(false);
CONNECTU(&eth, newConnection, this, newConnection);
CONNECTU(&timeout_timer, tickEvent, this, cleanClients);
}
@@ -15,7 +16,7 @@ DispatcherServer::DispatcherServer(PIEthernet::Address addr) : eth(PIEthernet::T
DispatcherServer::~DispatcherServer() {
eth.close();
//piCoutObj << "server stoped";
// piCoutObj << "server stoped";
}
@@ -35,7 +36,7 @@ void DispatcherServer::picoutStatus() {
}
piCout << "Servers:";
auto it = c_servers.makeIterator();
while(it.next()){
while (it.next()) {
piCout << " " << it.key();
it.value()->printStatus();
}
@@ -52,14 +53,15 @@ void DispatcherServer::cleanClients() {
for (auto c: clients) {
if (!index_c_servers.contains(c) && !index_c_clients.contains(c)) {
if (!rm_clients.contains(c)) rm_clients << c;
} else rm_clients.removeAll(c);
} else
rm_clients.removeAll(c);
}
auto ss = c_servers.values();
for (auto c: ss) {
if (c->lastPing() > 15.0) {
piCout << "remove Server by ping timeout" << c->getConnection()->clientId();
PIVector<DispatcherClient *> cscv = c->getClients();
for(auto csc : cscv) {
for (auto csc: cscv) {
clients.removeAll(csc);
index_c_clients.remove(csc);
c->removeClient(csc);
@@ -79,7 +81,7 @@ void DispatcherServer::cleanClients() {
}
for (auto c: rmrf_clients) {
clients.removeAll(c);
if(index_c_servers.contains(c)) {
if (index_c_servers.contains(c)) {
c_servers.remove(c_servers.key(index_c_servers[c]));
index_c_servers.remove(c);
}
@@ -96,18 +98,17 @@ void DispatcherServer::updateConnectionsTile(TileList * tl) {
for (auto c: clients) {
PIString role = "Invalid";
switch (c->role()) {
case PICloud::TCP::Client : {
role = "Client";
case PICloud::TCP::Client: {
role = "Client";
CloudServer * cs = index_c_clients.value(c, nullptr);
if (cs) role += " \"" + cs->serverUUID().toHex().left(8) + "...\"";
} break;
case PICloud::TCP::Server : {
role = "Server";
case PICloud::TCP::Server: {
role = "Server";
CloudServer * cs = index_c_servers.value(c, nullptr);
if (cs) role += " \"" + cs->serverUUID().toHex().left(8) + "...\"";
} break;
default:
break;
default: break;
}
tl->content << TileList::Row(c->address() + " " + role, PIScreenTypes::CellFormat());
}
@@ -126,7 +127,9 @@ void DispatcherServer::updateServersTile(TileList * tl, PISet<const DispatcherCl
tl->content.clear();
auto mi = c_servers.makeIterator();
while (mi.next()) {
tl->content << TileList::Row(mi.value()->serverUUID().toHex().left(8) + "... - " + PIString::fromNumber(mi.value()->getClients().size()), PIScreenTypes::CellFormat());
tl->content << TileList::Row(mi.value()->serverUUID().toHex().left(8) + "... - " +
PIString::fromNumber(mi.value()->getClients().size()),
PIScreenTypes::CellFormat());
if (servers.contains(mi.value()->getConnection())) tl->selected << (tl->content.size_s() - 1);
}
map_mutex.unlock();
@@ -138,7 +141,7 @@ void DispatcherServer::updateClientsTile(TileList * tl, PISet<const DispatcherCl
tl->content.clear();
auto mi = c_servers.makeIterator();
while (mi.next()) {
for (auto c : mi.value()->getClients()) {
for (auto c: mi.value()->getClients()) {
if (servers.isEmpty() || servers.contains(mi.value()->getConnection()))
tl->content << TileList::Row(c->address(), PIScreenTypes::CellFormat());
}
@@ -150,7 +153,7 @@ void DispatcherServer::updateClientsTile(TileList * tl, PISet<const DispatcherCl
const DispatcherClient * DispatcherServer::getConnection(int index) {
const DispatcherClient * ret = nullptr;
map_mutex.lock();
if (index >=0 && index < clients.size_s()) ret = clients[index];
if (index >= 0 && index < clients.size_s()) ret = clients[index];
map_mutex.unlock();
return ret;
}
@@ -159,7 +162,7 @@ const DispatcherClient * DispatcherServer::getConnection(int index) {
const DispatcherClient * DispatcherServer::getServer(int index) {
const DispatcherClient * ret = nullptr;
map_mutex.lock();
if (index >=0 && index < clients.size_s()) {
if (index >= 0 && index < clients.size_s()) {
if (index_c_servers.contains(clients[index])) ret = clients[index];
}
map_mutex.unlock();
@@ -171,7 +174,7 @@ PISet<const DispatcherClient *> DispatcherServer::getServers(PISet<int> ids) {
PISet<const DispatcherClient *> ret;
if (ids.isEmpty()) return ret;
map_mutex.lock();
int i = 0;
int i = 0;
auto mi = c_servers.makeIterator();
while (mi.next()) {
if (ids.contains(i)) ret << mi.value()->getConnection();
@@ -187,9 +190,9 @@ void DispatcherServer::setMaxConnections(uint max_count) {
}
void DispatcherServer::disconnectClient(DispatcherClient *client) {
void DispatcherServer::disconnectClient(DispatcherClient * client) {
if (!clients.contains(client)) {
//piCoutObj << "INVALID client" << client;
// piCoutObj << "INVALID client" << client;
return;
}
piCoutObj << "remove ..." << client->clientId();
@@ -200,7 +203,7 @@ void DispatcherServer::disconnectClient(DispatcherClient *client) {
if (cs) {
piCoutObj << "remove Server" << client->clientId();
PIVector<DispatcherClient *> cscv = cs->getClients();
for(auto csc : cscv) {
for (auto csc: cscv) {
clients.removeAll(csc);
index_c_clients.remove(csc);
cs->removeClient(csc);
@@ -217,21 +220,21 @@ void DispatcherServer::disconnectClient(DispatcherClient *client) {
cc->removeClient(client);
index_c_clients.remove(client);
}
//client->close();
// client->close();
rmrf_clients << client;
map_mutex.unlock();
piCoutObj << "remove done" << client->clientId();
}
void DispatcherServer::newConnection(PIEthernet *cl) {
void DispatcherServer::newConnection(PIEthernet * cl) {
if (clients.size() >= max_connections) {
delete cl;
return;
}
DispatcherClient * client = new DispatcherClient(cl, client_gid++);
CONNECTU(client, disconnectEvent, this, disconnectClient);
CONNECTL(client, registerServer, [this](const PIByteArray & sname, DispatcherClient * c){
CONNECTL(client, registerServer, [this](const PIByteArray & sname, DispatcherClient * c) {
map_mutex.lock();
CloudServer * cs = c_servers.value(sname, nullptr);
if (cs) {
@@ -246,7 +249,7 @@ void DispatcherServer::newConnection(PIEthernet *cl) {
}
map_mutex.unlock();
});
CONNECTL(client, registerClient, [this](const PIByteArray & sname, DispatcherClient * c){
CONNECTL(client, registerClient, [this](const PIByteArray & sname, DispatcherClient * c) {
map_mutex.lock();
CloudServer * cs = c_servers.value(sname, nullptr);
if (cs) {
@@ -260,7 +263,7 @@ void DispatcherServer::newConnection(PIEthernet *cl) {
}
map_mutex.unlock();
});
//piCoutObj << "add client" << client;
// piCoutObj << "add client" << client;
map_mutex.lock();
clients.push_back(client);
map_mutex.unlock();

View File

@@ -8,6 +8,7 @@ class TileList;
class DispatcherServer: public PIObject {
PIOBJECT(DispatcherServer)
public:
DispatcherServer(PIEthernet::Address addr);
~DispatcherServer();
@@ -20,21 +21,21 @@ public:
const DispatcherClient * getServer(int index);
PISet<const DispatcherClient *> getServers(PISet<int> ids);
void setMaxConnections(uint max_count);
uint maxConnections() const {return max_connections;}
uint maxConnections() const { return max_connections; }
EVENT_HANDLER0(void, picoutStatus);
private:
EVENT_HANDLER1(void, newConnection, PIEthernet * , cl);
EVENT_HANDLER1(void, newConnection, PIEthernet *, cl);
EVENT_HANDLER1(void, disconnectClient, DispatcherClient *, client);
EVENT_HANDLER0(void, cleanClients);
PIEthernet eth;
PIVector<DispatcherClient*> clients;
PIVector<DispatcherClient *> clients;
PIMap<PIByteArray, CloudServer *> c_servers;
PIMap<const DispatcherClient *, CloudServer *> index_c_servers;
PIMap<const DispatcherClient *, CloudServer *> index_c_clients;
PIVector<DispatcherClient*> rm_clients;
PIVector<DispatcherClient*> rmrf_clients;
PIVector<DispatcherClient *> rm_clients;
PIVector<DispatcherClient *> rmrf_clients;
PITimer timeout_timer;
PIMutex map_mutex;
uint client_gid;

View File

@@ -1,156 +1,159 @@
/*
PIP - Platform Independent Primitives
PICloud dispatcher
Andrey Bychkov work.a.b@yandex.ru, 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 "pip.h"
#include "picrypt.h"
#include "piiostream.h"
#include "dispatcherserver.h"
using namespace PICoutManipulators;
void usage() {
piCout << Bold << "PIP Cloud Dispatcher";
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
piCout << Green << Bold << "Usage:" << Default << "\"picloud [-hsv] [-i <ip>] [-p <port>]\"" << NewLine;
piCout << Green << Bold << "Details:";
piCout << "-h --help " << Green << "- display this message and exit";
piCout << "-i --ip " << Green << "- listen address, default \"0.0.0.0\"";
piCout << "-p --port " << Green << "- listen port, default 10101";
piCout << "-s --screen " << Green << "- start with console UI";
piCout << "-v --verbose" << Green << "- print state (--screen ignore this flag)";
}
PIString confDir() {
return
#ifdef WINDOWS
PIDir::home().path() + "/AppData/Local"
#elif defined(MAC_OS)
PIDir::home().path() + "/Library/Preferences"
#elif defined(ANDROID)
PIString(".")
#else
PIDir::home().path() + "/.config"
#endif
+ "/SHS";
}
int main (int argc, char * argv[]) {
PICLI cli(argc, argv);
cli.addArgument("help");
cli.addArgument("ip", true);
cli.addArgument("port", true);
cli.addArgument("screen");
cli.addArgument("verbose");
if (cli.hasArgument("help")) {
usage();
return 0;
}
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
PIString conf_path = confDir();
PIDir::make(conf_path);
conf_path += "/picloud.conf";
uint max_connections = 1000;
if (!PIFile::isExists(conf_path)) {
PIFile f(conf_path, PIIODevice::ReadWrite);
PIIOTextStream ts(&f);
ts << "ip = " << addr.ipString() << "\n"
<< "port = " << addr.port() << "\n"
<< "max_connections = " << max_connections << "\n";
}
{
PIConfig conf(conf_path, PIIODevice::ReadOnly);
addr.setIP(conf.getValue("ip", addr.ipString()).toString());
addr.setPort(conf.getValue("port", addr.port()).toUShort());
max_connections = conf.getValue("max_connections", max_connections).toUInt();
}
PITimer status_timer;
if (cli.hasArgument("ip"))
addr.setIP(cli.argumentValue("ip"));
if (cli.hasArgument("port"))
addr.setPort(cli.argumentValue("port").toInt());
DispatcherServer server(addr);
server.setMaxConnections(max_connections);
if (cli.hasArgument("screen")) {
PISet<const DispatcherClient *> sel_servers;
PIScreen screen(false);
PIScreenTile maintile("PICloud Dispatcher", PIScreenTypes::Horizontal, PIScreenTypes::Expanding);
PIScreenTile tls[3];
TileList conn_tl(PIString(), TileList::MultiSelection);
TileList server_tl(PIString(), TileList::MultiSelection);
TileList client_tl(PIString(), TileList::MultiSelection);
tls[0].addTile(new TileSimple(TileSimple::Row("Connections", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
tls[0].addTile(&conn_tl);
tls[1].addTile(new TileSimple(TileSimple::Row("Servers", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
tls[1].addTile(&server_tl);
tls[2].addTile(new TileSimple(TileSimple::Row("Clients", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
tls[2].addTile(&client_tl);
CONNECTL(&screen, tileEvent, ([&](PIScreenTile * t, PIScreenTypes::TileEvent e){
if (t == (PIScreenTile *)&server_tl) {
if (e.type == TileList::SelectionChanged) {
sel_servers = server.getServers(server_tl.selected);
}
}
if (t == (PIScreenTile *)&conn_tl) {
if (e.type == TileList::RowPressed) {
sel_servers.clear();
server_tl.selected.clear();
const DispatcherClient * dc = server.getServer(e.data.toInt());
if (dc) sel_servers << dc;
}
}
}));
for (auto & a : tls) {
a.children()[0]->size_policy = PIScreenTypes::Fixed;
maintile.addTile(&a);
}
CONNECTL(&status_timer, tickEvent, [&](void *, int){
screen.lock();
server.updateConnectionsTile(&conn_tl);
server.updateServersTile(&server_tl, sel_servers);
server.updateClientsTile(&client_tl, server.getServers(server_tl.selected));
screen.unlock();
});
screen.enableExitCapture(PIKbdListener::F10);
screen.rootTile()->addTile(new TileSimple(TileSimple::Row("PICloud Dispatcher " + addr.toString(), PIScreenTypes::CellFormat(PIScreenTypes::Yellow, PIScreenTypes::Default, PIScreenTypes::Bold))));
screen.rootTile()->addTile(&maintile);
screen.rootTile()->addTile(new TilePICout());
screen.start();
server.start();
status_timer.start(100);
screen.waitForFinish();
} else {
PIKbdListener ls;
ls.enableExitCapture(PIKbdListener::F10);
ls.start();
server.start();
if (cli.hasArgument("verbose")) {
CONNECTU(&status_timer, tickEvent, &server, picoutStatus);
status_timer.start(1000);
}
WAIT_FOR_EXIT
}
return 0;
}
/*
PIP - Platform Independent Primitives
PICloud dispatcher
Andrey Bychkov work.a.b@yandex.ru, 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 "dispatcherserver.h"
#include "picrypt.h"
#include "piiostream.h"
#include "pip.h"
using namespace PICoutManipulators;
void usage() {
piCout << Bold << "PIP Cloud Dispatcher";
piCout << Cyan << "Version" << Bold << PIPVersion() << NewLine;
piCout << Green << Bold << "Usage:" << Default << "\"picloud [-hsv] [-i <ip>] [-p <port>]\"" << NewLine;
piCout << Green << Bold << "Details:";
piCout << "-h --help " << Green << "- display this message and exit";
piCout << "-i --ip " << Green << "- listen address, default \"0.0.0.0\"";
piCout << "-p --port " << Green << "- listen port, default 10101";
piCout << "-s --screen " << Green << "- start with console UI";
piCout << "-v --verbose" << Green << "- print state (--screen ignore this flag)";
}
PIString confDir() {
return
#ifdef WINDOWS
PIDir::home().path() + "/AppData/Local"
#elif defined(MAC_OS)
PIDir::home().path() + "/Library/Preferences"
#elif defined(ANDROID)
PIString(".")
#else
PIDir::home().path() + "/.config"
#endif
+ "/SHS";
}
int main(int argc, char * argv[]) {
PICLI cli(argc, argv);
cli.addArgument("help");
cli.addArgument("ip", true);
cli.addArgument("port", true);
cli.addArgument("screen");
cli.addArgument("verbose");
if (cli.hasArgument("help")) {
usage();
return 0;
}
PIEthernet::Address addr = PIEthernet::Address("0.0.0.0", 10101);
PIString conf_path = confDir();
PIDir::make(conf_path);
conf_path += "/picloud.conf";
uint max_connections = 1000;
if (!PIFile::isExists(conf_path)) {
PIFile f(conf_path, PIIODevice::ReadWrite);
PIIOTextStream ts(&f);
ts << "ip = " << addr.ipString() << "\n"
<< "port = " << addr.port() << "\n"
<< "max_connections = " << max_connections << "\n";
}
{
PIConfig conf(conf_path, PIIODevice::ReadOnly);
addr.setIP(conf.getValue("ip", addr.ipString()).toString());
addr.setPort(conf.getValue("port", addr.port()).toUShort());
max_connections = conf.getValue("max_connections", max_connections).toUInt();
}
PITimer status_timer;
if (cli.hasArgument("ip")) addr.setIP(cli.argumentValue("ip"));
if (cli.hasArgument("port")) addr.setPort(cli.argumentValue("port").toInt());
DispatcherServer server(addr);
server.setMaxConnections(max_connections);
if (cli.hasArgument("screen")) {
PISet<const DispatcherClient *> sel_servers;
PIScreen screen(false);
PIScreenTile maintile("PICloud Dispatcher", PIScreenTypes::Horizontal, PIScreenTypes::Expanding);
PIScreenTile tls[3];
TileList conn_tl(PIString(), TileList::MultiSelection);
TileList server_tl(PIString(), TileList::MultiSelection);
TileList client_tl(PIString(), TileList::MultiSelection);
tls[0].addTile(new TileSimple(
TileSimple::Row("Connections",
PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
tls[0].addTile(&conn_tl);
tls[1].addTile(new TileSimple(
TileSimple::Row("Servers", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
tls[1].addTile(&server_tl);
tls[2].addTile(new TileSimple(
TileSimple::Row("Clients", PIScreenTypes::CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Inverse))));
tls[2].addTile(&client_tl);
CONNECTL(&screen, tileEvent, ([&](PIScreenTile * t, PIScreenTypes::TileEvent e) {
if (t == (PIScreenTile *)&server_tl) {
if (e.type == TileList::SelectionChanged) {
sel_servers = server.getServers(server_tl.selected);
}
}
if (t == (PIScreenTile *)&conn_tl) {
if (e.type == TileList::RowPressed) {
sel_servers.clear();
server_tl.selected.clear();
const DispatcherClient * dc = server.getServer(e.data.toInt());
if (dc) sel_servers << dc;
}
}
}));
for (auto & a: tls) {
a.children()[0]->size_policy = PIScreenTypes::Fixed;
maintile.addTile(&a);
}
CONNECTL(&status_timer, tickEvent, [&](void *, int) {
screen.lock();
server.updateConnectionsTile(&conn_tl);
server.updateServersTile(&server_tl, sel_servers);
server.updateClientsTile(&client_tl, server.getServers(server_tl.selected));
screen.unlock();
});
screen.enableExitCapture(PIKbdListener::F10);
screen.rootTile()->addTile(
new TileSimple(TileSimple::Row("PICloud Dispatcher " + addr.toString(),
PIScreenTypes::CellFormat(PIScreenTypes::Yellow, PIScreenTypes::Default, PIScreenTypes::Bold))));
screen.rootTile()->addTile(&maintile);
screen.rootTile()->addTile(new TilePICout());
screen.start();
server.start();
status_timer.start(100);
screen.waitForFinish();
} else {
PIKbdListener ls;
ls.enableExitCapture(PIKbdListener::F10);
ls.start();
server.start();
if (cli.hasArgument("verbose")) {
CONNECTU(&status_timer, tickEvent, &server, picoutStatus);
status_timer.start(1000);
}
WAIT_FOR_EXIT
}
return 0;
}