diff --git a/libs/cloud/picloudbase.cpp b/libs/cloud/picloudbase.cpp index bd9c9b77..10110a31 100644 --- a/libs/cloud/picloudbase.cpp +++ b/libs/cloud/picloudbase.cpp @@ -2,7 +2,7 @@ PICloudBase::PICloudBase() : eth(PIEthernet::TCP_Client), streampacker(ð), tcp(&streampacker) { - + eth.setDebug(false); } diff --git a/libs/cloud/picloudclient.cpp b/libs/cloud/picloudclient.cpp index 06239090..d959a57d 100644 --- a/libs/cloud/picloudclient.cpp +++ b/libs/cloud/picloudclient.cpp @@ -25,10 +25,10 @@ PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) tcp.setRole(PICloud::TCP::Client); setName("cloud_client"); is_connected = false; - CONNECTL(ð, connected, [this](){tcp.sendStart();}); + CONNECTL(ð, connected, [this](){opened_ = true; tcp.sendStart();}); CONNECTU(&streampacker, packetReceiveEvent, this, _readed); CONNECTL(ð, disconnected, [this](bool){ - piCoutObj << "disconnected"; +// piCoutObj << "disconnected"; opened_ = false; is_connected = false; cond_connect.notifyOne(); diff --git a/libs/cloud/picloudserver.cpp b/libs/cloud/picloudserver.cpp index 74261d67..0a07b67b 100644 --- a/libs/cloud/picloudserver.cpp +++ b/libs/cloud/picloudserver.cpp @@ -32,6 +32,9 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode) opened_ = false; piMSleep(100); }); + CONNECTL(&ping_timer, tickEvent, [this] (void *, int){ + if (eth.isConnected()) tcp.sendPing(); + }); } @@ -58,8 +61,10 @@ bool PICloudServer::openDevice() { bool op = eth.connect(PIEthernet::Address::resolve(path()), false); if (op) { eth.startThreadedRead(); + ping_timer.start(5000); return true; } + ping_timer.stop(); eth.close(); return false; } diff --git a/libs/cloud/picloudtcp.cpp b/libs/cloud/picloudtcp.cpp index 7f1e0d38..def39395 100644 --- a/libs/cloud/picloudtcp.cpp +++ b/libs/cloud/picloudtcp.cpp @@ -87,7 +87,7 @@ int PICloud::TCP::sendData(const PIByteArray & data) { PIByteArray ba; ba << header; ba.append(data); -// piCout << "sendData" << ba.toHex(); +// piCout << "[PICloud::TCP] sendData" << ba.toHex(); streampacker->send(ba); return data.size_s(); } @@ -103,6 +103,15 @@ int PICloud::TCP::sendData(const PIByteArray & data, uint client_id) { } +void PICloud::TCP::sendPing() { + header.type = PICloud::TCP::Ping; + PIByteArray ba; + ba << header; + ba.append(suuid); + streampacker->send(ba); +} + + PIPair PICloud::TCP::parseHeader(PIByteArray & ba) { PIPair ret; ret.first = InvalidType; diff --git a/libs/io_utils/pibroadcast.cpp b/libs/io_utils/pibroadcast.cpp index d73952ac..0a064ea5 100644 --- a/libs/io_utils/pibroadcast.cpp +++ b/libs/io_utils/pibroadcast.cpp @@ -203,6 +203,10 @@ void PIBroadcast::initAll(PIVector al) { void PIBroadcast::send(const PIByteArray & data) { + if (!isRunning()) { + reinit(); + PIThread::start(3000); + } PIByteArray cd = cryptData(data); if (cd.isEmpty()) return; PIMutexLocker ml(mcast_mutex); diff --git a/libs/main/cloud/picloudserver.h b/libs/main/cloud/picloudserver.h index e0493564..899ad326 100644 --- a/libs/main/cloud/picloudserver.h +++ b/libs/main/cloud/picloudserver.h @@ -78,6 +78,7 @@ private: PIVector clients_; PIMap index_clients; + PITimer ping_timer; mutable PIMutex clients_mutex; }; diff --git a/libs/main/cloud/picloudtcp.h b/libs/main/cloud/picloudtcp.h index 16dfd801..c941b51c 100644 --- a/libs/main/cloud/picloudtcp.h +++ b/libs/main/cloud/picloudtcp.h @@ -52,6 +52,7 @@ public: Connect = 1, Disconnect = 2, Data = 3, + Ping = 4, }; TCP(PIStreamPacker * s); @@ -65,6 +66,7 @@ public: void sendDisconnected(uint client_id); int sendData(const PIByteArray & data); int sendData(const PIByteArray & data, uint client_id); + void sendPing(); PIPair parseHeader(PIByteArray & ba); PIByteArray parseData(PIByteArray & ba); PIPair parseDataServer(PIByteArray & ba); diff --git a/main.cpp b/main.cpp index 9f4f46d9..66ab2f11 100644 --- a/main.cpp +++ b/main.cpp @@ -2,25 +2,7 @@ int main(int argc, char * argv[]) { - PIByteArray v0 = PIByteArray::fromHex("01020304"); - PIByteArray v1 = PIByteArray::fromHex("01020304"); - piCout << "==" << (v0 == v1) << ", !=" << (v0 != v1) << ", <" << (v0 < v1) << ", >" << (v0 > v1); - v0 = PIByteArray::fromHex("0102030405"); - v1 = PIByteArray::fromHex("01020304"); - piCout << "==" << (v0 == v1) << ", !=" << (v0 != v1) << ", <" << (v0 < v1) << ", >" << (v0 > v1); - v0 = PIByteArray::fromHex("01020304"); - v1 = PIByteArray::fromHex("0102030405"); - piCout << "==" << (v0 == v1) << ", !=" << (v0 != v1) << ", <" << (v0 < v1) << ", >" << (v0 > v1); - v0 = PIByteArray::fromHex("01020404"); - v1 = PIByteArray::fromHex("01020304"); - piCout << "==" << (v0 == v1) << ", !=" << (v0 != v1) << ", <" << (v0 < v1) << ", >" << (v0 > v1); - v0 = PIByteArray::fromHex("0102040405"); - v1 = PIByteArray::fromHex("01020304"); - piCout << "==" << (v0 == v1) << ", !=" << (v0 != v1) << ", <" << (v0 < v1) << ", >" << (v0 > v1); - v0 = PIByteArray::fromHex("01020404"); - v1 = PIByteArray::fromHex("0102030405"); - piCout << "==" << (v0 == v1) << ", !=" << (v0 != v1) << ", <" << (v0 < v1) << ", >" << (v0 > v1); - /*PICLI cli(argc, argv); + PICLI cli(argc, argv); PITimer tm; cli.addArgument("connect", true); cli.addArgument("name", true); @@ -77,6 +59,6 @@ int main(int argc, char * argv[]) { PIKbdListener ls; ls.enableExitCapture(PIKbdListener::F10); ls.start(); - WAIT_FOR_EXIT*/ + WAIT_FOR_EXIT return 0; } diff --git a/utils/cloud_dispatcher/cloudserver.cpp b/utils/cloud_dispatcher/cloudserver.cpp index d3c58aee..09241e9b 100644 --- a/utils/cloud_dispatcher/cloudserver.cpp +++ b/utils/cloud_dispatcher/cloudserver.cpp @@ -7,6 +7,8 @@ CloudServer::CloudServer(DispatcherClient * c, const PIByteArray & sname) : serv DispatcherClient * cl = index_clients.value(id, nullptr); if (cl) cl->sendData(ba); })); + CONNECTL(c, pingReceived, [this]() {last_ping.reset();}); + last_ping.reset(); } @@ -23,6 +25,7 @@ PIByteArray CloudServer::serverUUID() const { void CloudServer::addClient(DispatcherClient * c) { + last_ping.reset(); clients << c; index_clients.insert(c->clientId(), c); c->sendConnected(1); @@ -37,6 +40,7 @@ void CloudServer::addClient(DispatcherClient * c) { void CloudServer::removeClient(DispatcherClient * c) { + last_ping.reset(); clients.removeOne(c); index_clients.removeOne(c->clientId()); server->sendDisconnected(c->clientId()); @@ -48,6 +52,11 @@ PIVector CloudServer::getClients() { } +double CloudServer::lastPing() { + return last_ping.elapsed_s(); +} + + void CloudServer::printStatus() { piCout << " " << "Clients for" << server->address() << server_uuid.toHex() << ":"; for (auto c: clients) { diff --git a/utils/cloud_dispatcher/cloudserver.h b/utils/cloud_dispatcher/cloudserver.h index 14573a67..bd6fd5dd 100644 --- a/utils/cloud_dispatcher/cloudserver.h +++ b/utils/cloud_dispatcher/cloudserver.h @@ -15,12 +15,14 @@ public: PIVector getClients(); EVENT_HANDLER0(void, printStatus); const DispatcherClient * getConnection() const {return server;} + double lastPing(); private: DispatcherClient * server; PIVector clients; PIMap index_clients; PIByteArray server_uuid; + PITimeMeasurer last_ping; }; #endif // CLOUDSERVER_H diff --git a/utils/cloud_dispatcher/dispatcherclient.cpp b/utils/cloud_dispatcher/dispatcherclient.cpp index cc86dcd6..936bfca7 100644 --- a/utils/cloud_dispatcher/dispatcherclient.cpp +++ b/utils/cloud_dispatcher/dispatcherclient.cpp @@ -72,10 +72,11 @@ void DispatcherClient::disconnected(bool withError) { void DispatcherClient::readed(PIByteArray & ba) { -// piCout << size; PIPair hdr = tcp.parseHeader(ba); +// piCoutObj << "readed" << hdr.first << hdr.second; if (hdr.first == PICloud::TCP::InvalidType) { disconnected(true); + piCoutObj << "invalid message"; return; } if (authorised) { @@ -87,7 +88,7 @@ void DispatcherClient::readed(PIByteArray & ba) { disconnected(false); return; case PICloud::TCP::Data: -// piCoutObj << "TCP::Data"; + //piCoutObj << "TCP::Data" << tcp.role(); if (tcp.role() == PICloud::TCP::Client) { PIByteArray data = tcp.parseData(ba); if (!data.isEmpty()) dataReaded(data); @@ -99,11 +100,15 @@ void DispatcherClient::readed(PIByteArray & ba) { else piCoutObj << "invalid data from server"; } return; + case PICloud::TCP::Ping: + pingReceived(); + return; default: + piCoutObj << "unknown data"; //disconnected(true); return; } - } + } else piCoutObj << "invalid role"; } else { switch (hdr.first) { case PICloud::TCP::Connect: { @@ -111,7 +116,8 @@ void DispatcherClient::readed(PIByteArray & ba) { PIByteArray sn = tcp.parseConnect_d(ba); if (hdr.second == PICloud::TCP::Server) registerServer(sn, this); if (hdr.second == PICloud::TCP::Client) registerClient(sn, this); - return;} + return; + } case PICloud::TCP::Disconnect: disconnected(false); return; diff --git a/utils/cloud_dispatcher/dispatcherclient.h b/utils/cloud_dispatcher/dispatcherclient.h index 90b20461..9fb5bdbf 100644 --- a/utils/cloud_dispatcher/dispatcherclient.h +++ b/utils/cloud_dispatcher/dispatcherclient.h @@ -28,6 +28,7 @@ public: EVENT2(registerClient, const PIByteArray &, sname, DispatcherClient *, client) EVENT1(dataReaded, PIByteArray &, ba) EVENT2(dataReadedServer, uint, id, PIByteArray &, ba) + EVENT0(pingReceived) private: EVENT_HANDLER1(void, readed, PIByteArray &, data); diff --git a/utils/cloud_dispatcher/dispatcherserver.cpp b/utils/cloud_dispatcher/dispatcherserver.cpp index 6ebc0094..b5e53228 100644 --- a/utils/cloud_dispatcher/dispatcherserver.cpp +++ b/utils/cloud_dispatcher/dispatcherserver.cpp @@ -53,6 +53,10 @@ void DispatcherServer::cleanClients() { if (!rm_clients.contains(c)) rm_clients << c; } else rm_clients.removeAll(c); } + auto ss = c_servers.values(); + for (auto c: ss) { + if (c->lastPing() > 15.0) rmrf_clients << const_cast(c->getConnection()); + } for (auto c: rm_clients) { if (clients.contains(c)) { rmrf_clients << c; @@ -60,7 +64,10 @@ void DispatcherServer::cleanClients() { } for (auto c: rmrf_clients) { clients.removeAll(c); - index_c_servers.remove(c); + if(index_c_servers.contains(c)) { + c_servers.remove(c_servers.key(index_c_servers[c])); + index_c_servers.remove(c); + } index_c_clients.remove(c); rm_clients.removeAll(c); } @@ -226,9 +233,9 @@ void DispatcherServer::newConnection(PIEthernet *cl) { CloudServer * cs = c_servers.value(sname, nullptr); if (cs) { piCoutObj << "add new Client to Server ->" << sname.toHex(); + c->authorise(true); cs->addClient(c); index_c_clients.insert(c, cs); - c->authorise(true); } else { rm_clients << c; piCoutObj << "Client can't connect to Server ->" << sname.toHex();