4
1
mirror of https://github.com/QuasarApp/Heart.git synced 2025-05-11 00:49:42 +00:00

fixed the senderdata class on the HanoiTowers but tests has been broken

This commit is contained in:
Andrei Yankovich 2021-03-18 10:16:09 +03:00
parent 95a44f4af2
commit 7a88ea7e9d
6 changed files with 150 additions and 134 deletions

@ -1,34 +0,0 @@
/*
* Copyright (C) 2021-2021 QuasarApp.
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
#include "socketfactory.h"
#include <abstractnode.h>
namespace QH {
SocketFactory::SocketFactory(AbstractNode *nodeInstance):
Async(nodeInstance) {
assert(nodeInstance && "The SocketFactory must be initialize with the mail node object.");
_abstractNodeInstance = nodeInstance;
}
bool SocketFactory::registerSocket(QAbstractSocket *socket,
const HostAddress *clientAddress) {
return asyncLauncher(std::bind(&SocketFactory::registerSocketPrivete,
this, socket, clientAddress), false);
}
bool SocketFactory::registerSocketPrivete(QAbstractSocket *socket,
const HostAddress *clientAddress) {
return _abstractNodeInstance->registerSocket(socket, clientAddress);
}
}

@ -1,47 +0,0 @@
/*
* Copyright (C) 2021-2021 QuasarApp.
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
#ifndef SOCKETFACTORY_H
#define SOCKETFACTORY_H
#include <async.h>
class QAbstractSocket;
namespace QH {
To - Do // Remove This class and create a new general class for moving invokes into another threads.
class HostAddress;
class AbstractNode;
/**
* @brief The SocketFactory class prepare socket opbjects.
* This class is thread wraper for the registerSocket socket method of the AbstractNode class.
* The registerSocket method of this class just invoke the AbstractNode::registerSocket method on new thread.
*/
class SocketFactory : public Async
{
Q_OBJECT
public:
SocketFactory(AbstractNode* nodeInstance);
/**
* @brief registerSocket This method registration new socket object.
* @param socket This is incomming socket pointer.
* @param address This is host address of socket. By default is nullptr.
* Set this value for nodes created on this host.
* @return return true if the scoeket has been registered successful.
*/
bool registerSocket(QAbstractSocket *socket, const HostAddress* clientAddress = nullptr);
private:
bool registerSocketPrivete(QAbstractSocket *socket, const HostAddress* clientAddress);
AbstractNode *_abstractNodeInstance = nullptr;
};
}
#endif // SOCKETFACTORY_H

@ -21,7 +21,7 @@
#include <QMetaObject>
#include <QtConcurrent>
#include <closeconnection.h>
#include <socketfactory.h>
#include "asynclauncher.h"
#include "receivedata.h"
namespace QH {
@ -36,10 +36,9 @@ AbstractNode::AbstractNode( QObject *ptr):
_senderThread = new QThread();
_senderThread->setObjectName("Sender");
_socketFactory = new SocketFactory(this);
_socketWorker = new AsyncLauncher(_senderThread);
_dataSender->moveToThread(_senderThread);
_socketFactory->moveToThread(_senderThread);
_senderThread->start();
@ -133,21 +132,26 @@ void AbstractNode::unBan(const HostAddress &target) {
}
bool AbstractNode::connectToHost(const HostAddress &address, SslMode mode) {
QTcpSocket *socket;
if (mode == SslMode::NoSSL) {
socket = new QTcpSocket(nullptr);
} else {
socket = new QSslSocket(nullptr);
}
if (!_socketFactory->registerSocket(socket, &address)) {
delete socket;
return false;
}
AsyncLauncher::Job action = [this, mode, address]() -> bool {
QTcpSocket *socket;
if (mode == SslMode::NoSSL) {
socket = new QTcpSocket(nullptr);
} else {
socket = new QSslSocket(nullptr);
}
socket->connectToHost(address, address.port());
if (!registerSocket(socket, &address)) {
delete socket;
return false;
}
return true;
socket->connectToHost(address, address.port());
return true;
};
return _socketWorker->run(action);
}
bool AbstractNode::connectToHost(const QString &domain, unsigned short port, SslMode mode) {
@ -167,19 +171,7 @@ bool AbstractNode::connectToHost(const QString &domain, unsigned short port, Ssl
}
if (!connectToHost(HostAddress{addresses.first(), port}, mode)) {
return;
}
auto hostObject = getInfoPtr(HostAddress{addresses.first(), port});
if (!hostObject) {
QuasarAppUtils::Params::log("The domain name :" + domain + " has connected bud not have network object!",
QuasarAppUtils::Error);
return;
}
hostObject->setInfo(info);
connectToHost(HostAddress{addresses.first(), port}, mode);
});
return true;
@ -217,6 +209,7 @@ AbstractNode::~AbstractNode() {
delete _dataSender;
delete _senderThread;
delete _socketWorker;
}
QSslConfiguration AbstractNode::getSslConfig() const {
@ -675,42 +668,62 @@ bool AbstractNode::changeTrust(const HostAddress &id, int diff) {
}
void AbstractNode::incomingSsl(qintptr socketDescriptor) {
QSslSocket *socket = new QSslSocket;
AsyncLauncher::Job action = [this, socketDescriptor]() -> bool {
QSslSocket *socket = new QSslSocket;
socket->setSslConfiguration(_ssl);
socket->setSslConfiguration(_ssl);
if (!isBanned(socket) && socket->setSocketDescriptor(socketDescriptor)) {
connect(socket, &QSslSocket::encrypted, [this, socket]() {
if (!registerSocket(socket)) {
socket->deleteLater();
}
});
connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
[socket](const QList<QSslError> &errors){
for (auto &error : errors) {
QuasarAppUtils::Params::log(error.errorString(), QuasarAppUtils::Error);
}
if (!isBanned(socket) && socket->setSocketDescriptor(socketDescriptor)) {
connect(socket, &QSslSocket::encrypted, [this, socket](){
if (!_socketFactory->registerSocket(socket)) {
socket->deleteLater();
}
});
});
connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
[socket](const QList<QSslError> &errors){
socket->startServerEncryption();
for (auto &error : errors) {
QuasarAppUtils::Params::log(error.errorString(), QuasarAppUtils::Error);
}
return true;
} else {
delete socket;
return false;
}
socket->deleteLater();
});
};
socket->startServerEncryption();
} else {
delete socket;
}
_socketWorker->run(action);
}
void AbstractNode::incomingTcp(qintptr socketDescriptor) {
QTcpSocket *socket = new QTcpSocket();
if (socket->setSocketDescriptor(socketDescriptor) && !isBanned(socket)) {
if (!_socketFactory->registerSocket(socket)) {
AsyncLauncher::Job action = [this, socketDescriptor]() -> bool {
QTcpSocket *socket = new QTcpSocket();
if (socket->setSocketDescriptor(socketDescriptor) && !isBanned(socket)) {
if (!registerSocket(socket)) {
delete socket;
return false;
}
} else {
delete socket;
return false;
}
} else {
delete socket;
}
return true;
};
_socketWorker->run(action);
}

@ -38,6 +38,7 @@ namespace QH {
class DataSender;
class ReceiveData;
class SocketFactory;
class AsyncLauncher;
namespace PKG {
class ErrorData;
@ -570,7 +571,7 @@ private:
QHash<HostAddress, ReceiveData*> _receiveData;
DataSender * _dataSender = nullptr;
SocketFactory * _socketFactory = nullptr;
AsyncLauncher * _socketWorker = nullptr;
QThread *_senderThread = nullptr;
QSet<QFutureWatcher <bool>*> _workers;

@ -0,0 +1,25 @@
/*
* Copyright (C) 2021-2021 QuasarApp.
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
#include "asynclauncher.h"
namespace QH {
AsyncLauncher::AsyncLauncher(QThread * thread, QObject *ptr):
Async(ptr) {
setThread(thread);
}
void AsyncLauncher::setThread(QThread *thread) {
moveToThread(thread);
}
bool AsyncLauncher::run(const Async::Job &action, bool wait) {
return asyncLauncher(action, wait);
}
}

@ -0,0 +1,58 @@
/*
* Copyright (C) 2021-2021 QuasarApp.
* Distributed under the lgplv3 software license, see the accompanying
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
#ifndef ASYNCLAUNCHER_H
#define ASYNCLAUNCHER_H
#include <async.h>
class QThread;
namespace QH {
/**
* @brief The AsyncLauncher class is wraper of the Async class for support moving invokes to thread of the current object.
* Exmaple:
* @code{cpp}
* QThread *thread = new QThread();
* AsyncLauncher async(thread);
* AsyncLauncher::Job action = []() -> bool {
* ...
* }
*
* async.run(action);
* @endcode
*/
class AsyncLauncher final: public Async
{
Q_OBJECT
public:
/**
* @brief AsyncLauncher This is base constructor of the AsyncLauncher object.
* @param thread This is pointer to the work thread. If you want to change thread in run time just use the setThread method.
* @param ptr This is QObject parent.
*/
AsyncLauncher(QThread * thread, QObject* ptr = nullptr);
/**
* @brief setThread This method sets new work thread.
* @param thread This is new value of the thread.
*/
void setThread(QThread * thread);
/**
* @brief run This method run the @a action function in the work thread of this object.
* @param action This is function for running in the work thread.
* @param wait This option for sets awaiting of the finishing the @a action function. By default this is false.
* @return true if the action started succesful when @a wait is false and return true if the @a action finished succesful if the @a wait is true.
*/
bool run(const Job &action, bool wait = false);
};
}
#endif // ASYNCLAUNCHER_H