Merge PR #555: TcpCommander: Add TCP server broadcast functionality to send data to all connected clients
commit
0e0cc51649
|
|
@ -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 ¶mTypeId, 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);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue