Merge PR #555: TcpCommander: Add TCP server broadcast functionality to send data to all connected clients

master
jenkins 2022-06-17 00:16:56 +02:00
commit 0e0cc51649
4 changed files with 59 additions and 26 deletions

View File

@ -54,9 +54,9 @@ void IntegrationPluginTcpCommander::setupThing(ThingSetupInfo *info)
// In case of a reconfigure, make sure we reconnect // In case of a reconfigure, make sure we reconnect
tcpSocket->disconnectFromHost(); tcpSocket->disconnectFromHost();
} }
connect(tcpSocket, &QTcpSocket::stateChanged, thing, [=](QAbstractSocket::SocketState state){ connect(tcpSocket, &QTcpSocket::stateChanged, thing, [=](QAbstractSocket::SocketState state){
thing->setStateValue(tcpClientConnectedStateTypeId, state == QAbstractSocket::ConnectedState); thing->setStateValue(tcpClientConnectedStateTypeId, state == QAbstractSocket::ConnectedState);
if (state == QAbstractSocket::UnconnectedState) { if (state == QAbstractSocket::UnconnectedState) {
QTimer::singleShot(10000, tcpSocket, [=](){ QTimer::singleShot(10000, tcpSocket, [=](){
qCDebug(dcTCPCommander()) << "Reconnecting to server" << address << port; qCDebug(dcTCPCommander()) << "Reconnecting to server" << address << port;
@ -64,12 +64,12 @@ void IntegrationPluginTcpCommander::setupThing(ThingSetupInfo *info)
}); });
} }
}); });
connect(tcpSocket, &QTcpSocket::readyRead, thing, [=](){ connect(tcpSocket, &QTcpSocket::readyRead, thing, [=](){
QByteArray data = tcpSocket->readAll(); QByteArray data = tcpSocket->readAll();
ParamList params; ParamList params;
params << Param(tcpClientTriggeredEventDataParamTypeId, data); params << Param(tcpClientTriggeredEventDataParamTypeId, data);
Event event(tcpClientTriggeredEventTypeId, thing->id(), params); emit emitEvent(Event(tcpClientTriggeredEventTypeId, thing->id(), params));
emitEvent(event);
}); });
tcpSocket->connectToHost(address, port); tcpSocket->connectToHost(address, port);
@ -85,17 +85,30 @@ void IntegrationPluginTcpCommander::setupThing(ThingSetupInfo *info)
// In case of reconfigure, make sure to re-setup the server // In case of reconfigure, make sure to re-setup the server
delete tcpServer; delete tcpServer;
} }
tcpServer = new TcpServer(port, this); tcpServer = new TcpServer(port, this);
tcpServer->setConfirmCommands(thing->setting(tcpServerSettingsConfirmCommandParamTypeId).toBool());
if (tcpServer->isValid()) { if (tcpServer->isValid()) {
m_tcpServers.insert(thing, tcpServer); m_tcpServers.insert(thing, tcpServer);
connect(thing, &Thing::settingChanged, tcpServer, [=](const ParamTypeId &paramTypeId, const QVariant &value){
if (paramTypeId == tcpServerSettingsConfirmCommandParamTypeId) {
tcpServer->setConfirmCommands(value.toBool());
}
});
connect(tcpServer, &TcpServer::connectionCountChanged, this, &IntegrationPluginTcpCommander::onTcpServerConnectionCountChanged); connect(tcpServer, &TcpServer::connectionCountChanged, this, &IntegrationPluginTcpCommander::onTcpServerConnectionCountChanged);
connect(tcpServer, &TcpServer::commandReceived, this, &IntegrationPluginTcpCommander::onTcpServerCommandReceived); connect(tcpServer, &TcpServer::commandReceived, this, &IntegrationPluginTcpCommander::onTcpServerCommandReceived);
return info->finish(Thing::ThingErrorNoError); info->finish(Thing::ThingErrorNoError);
// Set the initial connected state since the server is running
thing->setStateValue("connected", true);
return;
} else { } else {
tcpServer->deleteLater(); tcpServer->deleteLater();
qDebug(dcTCPCommander()) << "Could not open TCP Server"; qDebug(dcTCPCommander()) << "Could not open TCP Server";
return info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Error opening TCP port.")); info->finish(Thing::ThingErrorSetupFailed, QT_TR_NOOP("Error opening TCP port."));
return;
} }
} }
} }
@ -158,15 +171,8 @@ void IntegrationPluginTcpCommander::onTcpServerConnectionCountChanged(int connec
{ {
TcpServer *tcpServer = static_cast<TcpServer *>(sender()); TcpServer *tcpServer = static_cast<TcpServer *>(sender());
Thing *thing = m_tcpServers.key(tcpServer); Thing *thing = m_tcpServers.key(tcpServer);
if (!thing) if (thing && thing->thingClassId() == tcpServerThingClassId) {
return; qDebug(dcTCPCommander()) << thing->name() << "Tcp Server Client connected";
qDebug(dcTCPCommander()) << thing->name() << "Tcp Server Client connected";
if (thing->thingClassId() == tcpServerThingClassId) {
if (connections > 0) {
thing->setStateValue(tcpServerConnectedStateTypeId, true);
} else {
thing->setStateValue(tcpServerConnectedStateTypeId, false);
}
thing->setStateValue(tcpServerConnectionCountStateTypeId, connections); thing->setStateValue(tcpServerConnectionCountStateTypeId, connections);
} }
} }
@ -177,10 +183,8 @@ void IntegrationPluginTcpCommander::onTcpServerCommandReceived(const QString &cl
Thing *thing = m_tcpServers.key(tcpServer); Thing *thing = m_tcpServers.key(tcpServer);
qDebug(dcTCPCommander()) << thing->name() << "Message received" << data; qDebug(dcTCPCommander()) << thing->name() << "Message received" << data;
Event event = Event(tcpServerTriggeredEventTypeId, thing->id());
ParamList params; ParamList params;
params.append(Param(tcpServerTriggeredEventDataParamTypeId, data)); params.append(Param(tcpServerTriggeredEventDataParamTypeId, data));
params.append(Param(tcpServerTriggeredEventClientIpParamTypeId, clientIp)); params.append(Param(tcpServerTriggeredEventClientIpParamTypeId, clientIp));
event.setParams(params); emit emitEvent(Event(tcpServerTriggeredEventTypeId, thing->id(), params));
emitEvent(event);
} }

View File

@ -89,6 +89,15 @@
"defaultValue": "22" "defaultValue": "22"
} }
], ],
"settingsTypes": [
{
"id": "27b8a43a-186e-46e6-b2e5-b6fa1dfaaaa9",
"name": "confirmCommand",
"displayName": "Autoconfirm commands",
"type": "bool",
"defaultValue": false
}
],
"stateTypes": [ "stateTypes": [
{ {
"id": "a2eb1619-261c-45ee-9587-6b5994633ad0", "id": "a2eb1619-261c-45ee-9587-6b5994633ad0",

View File

@ -61,11 +61,21 @@ TcpServer::~TcpServer()
{ {
} }
bool TcpServer::isValid() bool TcpServer::isValid() const
{ {
return m_tcpServer->isListening(); return m_tcpServer->isListening();
} }
bool TcpServer::confirmCommands() const
{
return m_confirmCommands;
}
void TcpServer::setConfirmCommands(bool confirmCommands)
{
m_confirmCommands = confirmCommands;
}
QHostAddress TcpServer::serverAddress() QHostAddress TcpServer::serverAddress()
{ {
return m_tcpServer->serverAddress(); return m_tcpServer->serverAddress();
@ -76,7 +86,7 @@ int TcpServer::serverPort()
return m_tcpServer->serverPort(); return m_tcpServer->serverPort();
} }
int TcpServer::connectionCount() int TcpServer::connectionCount() const
{ {
return m_clients.count(); return m_clients.count();
} }
@ -85,16 +95,19 @@ bool TcpServer::sendCommand(const QString &clientIp, const QByteArray &data)
{ {
bool success = false; bool success = false;
QHostAddress address(clientIp); QHostAddress address(clientIp);
bool broadcast = false;
if (address == QHostAddress(QHostAddress::AnyIPv4) || address == QHostAddress(QHostAddress::Broadcast))
broadcast = true;
foreach (QTcpSocket *client, m_clients) { foreach (QTcpSocket *client, m_clients) {
if (address == QHostAddress(QHostAddress::AnyIPv4) || client->peerAddress() == address) { if (broadcast || client->peerAddress() == address) {
qint64 len = client->write(data); qint64 len = client->write(data);
if (len == data.length()) { if (len == data.length()) {
success = true; success = true;
} }
} }
} }
qCWarning(dcTCPCommander()) << "No client matching the destination IP" << address.toString();
return success; return success;
} }
@ -125,7 +138,10 @@ void TcpServer::readData()
QTcpSocket *socket = static_cast<QTcpSocket *>(sender()); QTcpSocket *socket = static_cast<QTcpSocket *>(sender());
QByteArray data = socket->readAll(); QByteArray data = socket->readAll();
qDebug(dcTCPCommander()) << "TCP Server data received: " << data; qDebug(dcTCPCommander()) << "TCP Server data received: " << data;
socket->write("OK\n"); if (m_confirmCommands) {
socket->write("OK\n");
}
emit commandReceived(socket->peerAddress().toString(), data); emit commandReceived(socket->peerAddress().toString(), data);
} }

View File

@ -43,12 +43,16 @@ public:
explicit TcpServer(const quint16 &port, QObject *parent = nullptr); explicit TcpServer(const quint16 &port, QObject *parent = nullptr);
~TcpServer(); ~TcpServer();
bool isValid();
QHostAddress serverAddress();
QHostAddress serverAddress();
int serverPort(); int serverPort();
int connectionCount(); bool isValid() const;
bool confirmCommands() const;
void setConfirmCommands(bool confirmCommands);
int connectionCount() const;
bool sendCommand(const QString &clientIp, const QByteArray &data); bool sendCommand(const QString &clientIp, const QByteArray &data);
@ -65,7 +69,7 @@ private slots:
private: private:
QTcpServer *m_tcpServer = nullptr; QTcpServer *m_tcpServer = nullptr;
bool m_confirmCommands = false;
QList<QTcpSocket*> m_clients; QList<QTcpSocket*> m_clients;
}; };