picloud add server logics
This commit is contained in:
@@ -24,6 +24,7 @@
|
|||||||
PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) {
|
PICloudClient::PICloudClient(const PIString & path, PIIODevice::DeviceMode mode) : PIIODevice(path, mode) {
|
||||||
tcp.setRole(PICloud::TCP::Client);
|
tcp.setRole(PICloud::TCP::Client);
|
||||||
setName("cloud_client");
|
setName("cloud_client");
|
||||||
|
is_connected = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ bool PICloudClient::openDevice() {
|
|||||||
|
|
||||||
|
|
||||||
bool PICloudClient::closeDevice() {
|
bool PICloudClient::closeDevice() {
|
||||||
|
is_connected = false;
|
||||||
eth.stop();
|
eth.stop();
|
||||||
eth.close();
|
eth.close();
|
||||||
return true;
|
return true;
|
||||||
@@ -95,11 +97,25 @@ void PICloudClient::readed(uchar *data, int size) {
|
|||||||
mutex_buff.lock();
|
mutex_buff.lock();
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
||||||
if (hdr.second == tcp.role()) {
|
if (hdr.second == tcp.role()) {
|
||||||
piCoutObj << "readed" << ba.toHex();
|
switch (hdr.first) {
|
||||||
buff.append(data, size);
|
case PICloud::TCP::Connect:
|
||||||
cond_buff.notifyOne();
|
if (tcp.parseConnect(ba) == 0) is_connected = true;
|
||||||
|
break;
|
||||||
|
case PICloud::TCP::Disconnect:
|
||||||
|
is_connected = false;
|
||||||
|
eth.stop();
|
||||||
|
eth.close();
|
||||||
|
break;
|
||||||
|
case PICloud::TCP::Data:
|
||||||
|
buff.append(data, size);
|
||||||
|
cond_buff.notifyOne();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//piCoutObj << "readed" << ba.toHex();
|
||||||
}
|
}
|
||||||
mutex_buff.unlock();
|
mutex_buff.unlock();
|
||||||
while (buff.size() > threadedReadBufferSize()) piMSleep(100);
|
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,11 +29,12 @@ PICloudServer::PICloudServer(const PIString & path, PIIODevice::DeviceMode mode)
|
|||||||
|
|
||||||
|
|
||||||
PICloudServer::~PICloudServer() {
|
PICloudServer::~PICloudServer() {
|
||||||
for (auto & c : clients) {
|
|
||||||
c.stop();
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
stop();
|
stop();
|
||||||
|
eth.stop();
|
||||||
|
for (auto & c : clients) {
|
||||||
|
c->stop();
|
||||||
|
c->close();
|
||||||
|
}
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,9 +67,9 @@ bool PICloudServer::openDevice() {
|
|||||||
|
|
||||||
bool PICloudServer::closeDevice() {
|
bool PICloudServer::closeDevice() {
|
||||||
eth.stop();
|
eth.stop();
|
||||||
for (auto & c : clients) {
|
for (auto c : clients) {
|
||||||
c.stop();
|
c->stop();
|
||||||
c.close();
|
c->close();
|
||||||
}
|
}
|
||||||
eth.close();
|
eth.close();
|
||||||
return true;
|
return true;
|
||||||
@@ -85,7 +86,17 @@ int PICloudServer::writeDevice(const void * data, int max_size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PICloudServer::Client::Client(PICloudServer * srv) : server(srv) {
|
void PICloudServer::clientDisconnect(uint client_id) {
|
||||||
|
tcp.sendDisconnected(ð, client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PICloudServer::sendData(const PIByteArray & data, uint client_id) {
|
||||||
|
return tcp.sendData(ð, data, client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PICloudServer::Client::Client(PICloudServer * srv, uint id) : server(srv), client_id(id) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,10 +106,67 @@ bool PICloudServer::Client::openDevice() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool PICloudServer::Client::closeDevice() {
|
||||||
|
server->clientDisconnect(client_id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PICloudServer::Client::readDevice(void * read_to, int max_size) {
|
||||||
|
//piCoutObj << "readDevice";
|
||||||
|
mutex_buff.lock();
|
||||||
|
cond_buff.wait(mutex_buff, [this](){return !buff.isEmpty();});
|
||||||
|
int sz = piMini(max_size, buff.size());
|
||||||
|
memcpy(read_to, buff.data(), sz);
|
||||||
|
buff.remove(0, sz);
|
||||||
|
mutex_buff.unlock();
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PICloudServer::Client::writeDevice(const void * data, int max_size) {
|
||||||
|
return server->sendData(PIByteArray(data, max_size), client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PICloudServer::Client::pushBuffer(const PIByteArray & ba) {
|
||||||
|
mutex_buff.lock();
|
||||||
|
buff.append(ba);
|
||||||
|
cond_buff.notifyOne();
|
||||||
|
mutex_buff.unlock();
|
||||||
|
while (buff.size_s() > threadedReadBufferSize()) piMSleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PICloudServer::readed(uchar *data, int size) {
|
void PICloudServer::readed(uchar *data, int size) {
|
||||||
PIByteArray ba(data, size);
|
PIByteArray ba(data, size);
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> hdr = tcp.parseHeader(ba);
|
||||||
if (hdr.second == tcp.role()) {
|
if (hdr.second == tcp.role()) {
|
||||||
piCoutObj << "readed" << ba.toHex();
|
switch (hdr.first) {
|
||||||
|
case PICloud::TCP::Connect: {
|
||||||
|
uint id = tcp.parseConnect(ba);
|
||||||
|
Client * oc = index_clients.value(id, nullptr);
|
||||||
|
if (oc) {
|
||||||
|
tcp.sendDisconnected(ð, id);
|
||||||
|
} else {
|
||||||
|
Client * c = new Client(this, id);
|
||||||
|
clients << c;
|
||||||
|
index_clients.insert(id, c);
|
||||||
|
newConnection(c);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case PICloud::TCP::Disconnect: {
|
||||||
|
uint id = tcp.parseDisconnect(ba);
|
||||||
|
Client * oc = index_clients.value(id, nullptr);
|
||||||
|
if (oc) oc->close();
|
||||||
|
} break;
|
||||||
|
case PICloud::TCP::Data: {
|
||||||
|
PIPair<uint, PIByteArray> d = tcp.parseDataServer(ba);
|
||||||
|
Client * oc = index_clients.value(d.first, nullptr);
|
||||||
|
if (oc && !d.second.isEmpty()) oc->pushBuffer(d.second);
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ void PICloud::TCP::sendConnected(PIEthernet * eth, uint client_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PICloud::TCP::sendDisconnected(PIEthernet * eth, uint client_id) {
|
||||||
|
header.type = PICloud::TCP::Disconnect;
|
||||||
|
PIByteArray ba;
|
||||||
|
ba << header << client_id;
|
||||||
|
eth->send(ba);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void PICloud::TCP::sendData(PIEthernet * eth, const PIByteArray & data) {
|
void PICloud::TCP::sendData(PIEthernet * eth, const PIByteArray & data) {
|
||||||
header.type = PICloud::TCP::Data;
|
header.type = PICloud::TCP::Data;
|
||||||
PIByteArray ba;
|
PIByteArray ba;
|
||||||
@@ -71,6 +79,16 @@ void PICloud::TCP::sendData(PIEthernet * eth, const PIByteArray & data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PICloud::TCP::sendData(PIEthernet * eth, const PIByteArray & data, uint client_id) {
|
||||||
|
header.type = PICloud::TCP::Data;
|
||||||
|
PIByteArray ba;
|
||||||
|
ba << header << client_id;
|
||||||
|
ba.append(data);
|
||||||
|
if (eth->send(ba)) return data.size_s();
|
||||||
|
else return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteArray & ba) {
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteArray & ba) {
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret;
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> ret;
|
||||||
ret.first = Invalid;
|
ret.first = Invalid;
|
||||||
@@ -88,11 +106,6 @@ PIPair<PICloud::TCP::Type, PICloud::TCP::Role> PICloud::TCP::parseHeader(PIByteA
|
|||||||
|
|
||||||
|
|
||||||
PIByteArray PICloud::TCP::parseData(PIByteArray & ba) {
|
PIByteArray PICloud::TCP::parseData(PIByteArray & ba) {
|
||||||
if (header.role == Server) {
|
|
||||||
PIString client;
|
|
||||||
ba >> client;
|
|
||||||
return ba;
|
|
||||||
}
|
|
||||||
if (header.role == Client) {
|
if (header.role == Client) {
|
||||||
return ba;
|
return ba;
|
||||||
}
|
}
|
||||||
@@ -100,8 +113,33 @@ PIByteArray PICloud::TCP::parseData(PIByteArray & ba) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PIString PICloud::TCP::parseConnect(PIByteArray & ba) {
|
PIPair<uint, PIByteArray> PICloud::TCP::parseDataServer(PIByteArray & ba) {
|
||||||
|
PIPair<uint, PIByteArray> ret;
|
||||||
|
ret.first = 0;
|
||||||
|
if (header.role == Server) {
|
||||||
|
ba >> ret.first;
|
||||||
|
ret.second = ba;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PIString PICloud::TCP::parseConnect_d(PIByteArray & ba) {
|
||||||
PIString ret;
|
PIString ret;
|
||||||
ba >> ret;
|
ba >> ret;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint PICloud::TCP::parseConnect(PIByteArray & ba) {
|
||||||
|
uint ret;
|
||||||
|
ba >> ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint PICloud::TCP::parseDisconnect(PIByteArray & ba) {
|
||||||
|
uint ret;
|
||||||
|
ba >> ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ private:
|
|||||||
PIByteArray buff;
|
PIByteArray buff;
|
||||||
PIMutex mutex_buff;
|
PIMutex mutex_buff;
|
||||||
PIConditionVariable cond_buff;
|
PIConditionVariable cond_buff;
|
||||||
|
std::atomic_bool is_connected;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PICLOUDCLIENT_H
|
#endif // PICLOUDCLIENT_H
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#define PICLOUDSERVER_H
|
#define PICLOUDSERVER_H
|
||||||
|
|
||||||
#include "picloudbase.h"
|
#include "picloudbase.h"
|
||||||
|
#include "piconditionvar.h"
|
||||||
|
|
||||||
|
|
||||||
class PIP_CLOUD_EXPORT PICloudServer : public PIIODevice, private PICloudBase
|
class PIP_CLOUD_EXPORT PICloudServer : public PIIODevice, private PICloudBase
|
||||||
@@ -36,12 +37,22 @@ public:
|
|||||||
|
|
||||||
class Client : public PIIODevice {
|
class Client : public PIIODevice {
|
||||||
PIIODEVICE(PICloudServer::Client)
|
PIIODEVICE(PICloudServer::Client)
|
||||||
|
friend class PICloudServer;
|
||||||
public:
|
public:
|
||||||
Client(PICloudServer * srv = nullptr);
|
Client(PICloudServer * srv = nullptr, uint id = 0);
|
||||||
protected:
|
protected:
|
||||||
bool openDevice();
|
bool openDevice();
|
||||||
|
bool closeDevice();
|
||||||
|
int readDevice(void * read_to, int max_size);
|
||||||
|
int writeDevice(const void * data, int max_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void pushBuffer(const PIByteArray & ba);
|
||||||
PICloudServer * server;
|
PICloudServer * server;
|
||||||
|
uint client_id;
|
||||||
|
PIByteArray buff;
|
||||||
|
PIMutex mutex_buff;
|
||||||
|
PIConditionVariable cond_buff;
|
||||||
};
|
};
|
||||||
|
|
||||||
void setServerName(const PIString & server_name);
|
void setServerName(const PIString & server_name);
|
||||||
@@ -56,8 +67,11 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
EVENT_HANDLER2(void, readed, uchar * , data, int, size);
|
EVENT_HANDLER2(void, readed, uchar * , data, int, size);
|
||||||
|
void clientDisconnect(uint client_id);
|
||||||
|
int sendData(const PIByteArray & data, uint client_id);
|
||||||
|
|
||||||
PIVector<Client> clients;
|
PIVector<Client *> clients;
|
||||||
|
PIMap<uint, Client *> index_clients;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PICLOUDSERVER_H
|
#endif // PICLOUDSERVER_H
|
||||||
|
|||||||
@@ -58,10 +58,15 @@ public:
|
|||||||
|
|
||||||
void sendStart(PIEthernet * eth);
|
void sendStart(PIEthernet * eth);
|
||||||
void sendConnected(PIEthernet * eth, uint client_id);
|
void sendConnected(PIEthernet * eth, uint client_id);
|
||||||
|
void sendDisconnected(PIEthernet * eth, uint client_id);
|
||||||
void sendData(PIEthernet * eth, const PIByteArray & data);
|
void sendData(PIEthernet * eth, const PIByteArray & data);
|
||||||
|
int sendData(PIEthernet * eth, const PIByteArray & data, uint client_id);
|
||||||
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
PIPair<PICloud::TCP::Type, PICloud::TCP::Role> parseHeader(PIByteArray & ba);
|
||||||
PIByteArray parseData(PIByteArray & ba);
|
PIByteArray parseData(PIByteArray & ba);
|
||||||
PIString parseConnect(PIByteArray & ba);
|
PIPair<uint, PIByteArray> parseDataServer(PIByteArray & ba);
|
||||||
|
PIString parseConnect_d(PIByteArray & ba);
|
||||||
|
uint parseConnect(PIByteArray & ba);
|
||||||
|
uint parseDisconnect(PIByteArray & ba);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Header {
|
struct Header {
|
||||||
|
|||||||
@@ -40,7 +40,9 @@ void CloudServer::printStatus() {
|
|||||||
for (auto c: clients) {
|
for (auto c: clients) {
|
||||||
piCout << " " << c->address() << c->clientId();
|
piCout << " " << c->address() << c->clientId();
|
||||||
}
|
}
|
||||||
for (auto c: clients) c->sendData(PIByteArray::fromHex("000000"));
|
for (auto c: clients) {
|
||||||
server->sendData(PIByteArray::fromHex("000000"));
|
c->sendData(PIByteArray::fromHex("000000"));
|
||||||
|
server->sendDataToClient(PIByteArray::fromHex("000000"), c->clientId());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,14 @@ void DispatcherClient::sendConnected() {
|
|||||||
|
|
||||||
|
|
||||||
void DispatcherClient::sendData(const PIByteArray & data) {
|
void DispatcherClient::sendData(const PIByteArray & data) {
|
||||||
tcp.sendData(eth, data);
|
if (tcp.role() == PICloud::TCP::Client) tcp.sendData(eth, data);
|
||||||
|
else piCoutObj << "error sendData, invalid role";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DispatcherClient::sendDataToClient(const PIByteArray & data, uint client_id) {
|
||||||
|
if (tcp.role() == PICloud::TCP::Server) tcp.sendData(eth, data, client_id);
|
||||||
|
else piCoutObj << "error sendDataToClient, invalid role";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,7 +79,7 @@ void DispatcherClient::readed(uchar *data, int size) {
|
|||||||
switch (hdr.first) {
|
switch (hdr.first) {
|
||||||
case PICloud::TCP::Connect: {
|
case PICloud::TCP::Connect: {
|
||||||
tcp.setRole(hdr.second);
|
tcp.setRole(hdr.second);
|
||||||
PIString sn = tcp.parseConnect(ba);
|
PIString sn = tcp.parseConnect_d(ba);
|
||||||
if (hdr.second == PICloud::TCP::Server) registerServer(sn, this);
|
if (hdr.second == PICloud::TCP::Server) registerServer(sn, this);
|
||||||
if (hdr.second == PICloud::TCP::Client) registerClient(sn, this);
|
if (hdr.second == PICloud::TCP::Client) registerClient(sn, this);
|
||||||
return;}
|
return;}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
void close();
|
void close();
|
||||||
void sendConnected();
|
void sendConnected();
|
||||||
void sendData(const PIByteArray & data);
|
void sendData(const PIByteArray & data);
|
||||||
|
void sendDataToClient(const PIByteArray & data, uint client_id);
|
||||||
PIString address();
|
PIString address();
|
||||||
uint clientId() const {return client_id;}
|
uint clientId() const {return client_id;}
|
||||||
EVENT1(disconnectEvent, DispatcherClient *, client)
|
EVENT1(disconnectEvent, DispatcherClient *, client)
|
||||||
|
|||||||
Reference in New Issue
Block a user