4
1
mirror of https://github.com/QuasarApp/Heart.git synced 2025-05-12 09:29:41 +00:00

added commandHandler method

This commit is contained in:
Andrei Yankovich 2021-09-25 14:26:47 +03:00
parent a045bf3287
commit 5523a6c5a7
2 changed files with 85 additions and 28 deletions
Heart

@ -99,7 +99,11 @@ class Abstract;
* this implementation have a methods for send and receive data messages,
* and work with crypto method for crease a security connections betwin nodes.
* AbstractNode - is thread save class.
*
* @note For correctly working this class you should be register all you data types using the AbstractNode::registerPackageType method.
* @see AbstractData
* @see AbstractNode::registerPackageType
* @see AbstractNode::parsePackage
*/
class HEARTSHARED_EXPORT AbstractNode : public QTcpServer, public SoftDelete
{
@ -110,6 +114,7 @@ public:
/**
* @brief AbstractNode - Base constructor of node.
* @param ptr - Pointrt to parent Qt object, the AbstractNode class is Q_OBJECT.
* @note For correctly working this class you should be register all you data types using the AbstractNode::registerPackageType method.
*/
AbstractNode(QObject * ptr = nullptr);
~AbstractNode() override;
@ -305,6 +310,7 @@ protected:
return parentResult;
}
// you can use parsing without the commandHandler method
if (H_16<MyCommand>() == pkg->cmd()) {
BaseId requesterId = getSender(sender, &obj);
@ -321,6 +327,13 @@ protected:
}
// Or with the commandHandler method
auto result = commandHandler<MyPackage>(&MyClass::processMyPackage, pkg, sender, pkgHeader);
if (result != QH::ParserResult::NotProcessed) {
return result;
}
return ParserResult::NotProcessed;
}
* \endcode
@ -329,7 +342,8 @@ protected:
* @param pkgHeader This is header of the incoming packet is used to create a response.
* @return item of ParserResult. For more information see The ParserResult enum.
*/
virtual ParserResult parsePackage(const QSharedPointer<PKG::AbstractData> &pkg, const Header& pkgHeader, const AbstractNodeInfo* sender);
virtual ParserResult parsePackage(const QSharedPointer<PKG::AbstractData> &pkg,
const Header& pkgHeader, const AbstractNodeInfo* sender);
/**
* @brief sendPackage This method prepare and send to target address a package.
@ -537,6 +551,51 @@ protected:
*/
QList<HostAddress> connectionsList() const;
/**
* @brief commandHandler This method it is simple wrapper for the handle pacakges in the AbstractNode::parsePackage method.
* Exmaple of use :
* @code{cpp}
* auto result = commandHandler<MyPackage>(&MyClass::processMyPackage, pkg, sender, pkgHeader);
if (result != QH::ParserResult::NotProcessed) {
return result;
}
...
* @endcode
* @tparam PackageClass This is class name that you want handle. All classes mist be inhert of the QH::PKG::AbstractData class.
* @tparam HandlerMethod This is name of the handler method.
* The handler method should be support next signature:
* **bool Method(const QSharedPointer<QH::PKG::PackageClass> &, const QH::Header &pkgHeader, const QH::AbstractNodeInfo *sender)**.
* @param method This is handler method.
* @param pkg This is package data from the AbstractNode::parsePackage argumetns
* @param pkgHeader This is header of an incomming package.
* @param sender This is socket object of a sender that send this package.
* @return item of ParserResult. For more information see The ParserResult enum.
*
* @see AbstractNode::parsePackage
* @see ParserResult
*/
template<class PackageClass, class HandlerMethod>
inline ParserResult commandHandler(HandlerMethod method,
const QSharedPointer<QH::PKG::AbstractData> &pkg,
const QH::AbstractNodeInfo *sender,
const QH::Header &pkgHeader) {
if (H_16<PackageClass>() == pkg->cmd()) {
auto data = pkg.staticCast<PackageClass>();
if (!data->isValid()) {
return QH::ParserResult::Error;
}
if(!(*method(data, sender, pkgHeader))) {
return QH::ParserResult::Error;
}
return QH::ParserResult::Processed;
}
}
protected slots:
/**
* @brief nodeErrorOccured This slot invoked when error ocured in the @a nodeInfo.

@ -40,18 +40,6 @@ public:
bool isValid() const {
return AbstractData::isValid();
}; /
// override this method for copy object data from other to this object
bool copyFrom(const AbstractData *other) {
if (!AbstractData::copyFrom(other))
return false;
auto otherObject = dynamic_cast<const MyPackage*>(other);
if (!otherObject)
return false;
this->_data = otherObject->_data;
return true;
};
// your data for for server of client
std::string _data = "";
@ -76,6 +64,11 @@ protected:
* Example:
* \code{cpp}
class TestingServer: public QH::AbstractNode {
Q_OBJECT
public:
TestingServer() {
registerPackageType<MyPackage>();
}
protected:
// override this method for processed received data.
@ -87,23 +80,28 @@ protected:
return parentResult;
}
if (H_16<MyPackage>() == pkg.hdr.command) {
MyPackage obj(pkg);
BaseId requesterId = getSender(sender, &obj);
if (!obj.isValid()) {
badRequest(sender->networkAddress(), pkg.hdr);
return ParserResult::Error;
}
obj._data = "responce for client "
SendData(&obj, sender->networkAddress(), &pkg.hdr);
return ParserResult::Processed;
auto result = commandHandler<MyPackage>(&MyClass::processMyPackage, pkg, sender, pkgHeader);
if (result != QH::ParserResult::NotProcessed) {
return result;
}
return ParserResult::NotProcessed;
return ParserResult::NotProcessed;
}
bool processMyPackage(const QSharedPointer<MyPackage> &cardrequest,
const QH::AbstractNodeInfo *sender, const QH::Header &hdr) {
BaseId requesterId = getSender(sender, &cardrequest);
if (!cardrequest.isValid()) {
badRequest(sender->networkAddress(), hdr);
return ParserResult::Error;
}
cardrequest._data = "responce for client "
SendData(cardrequest, sender->networkAddress(), &pkg.hdr);
return ParserResult::Processed;
}
};
* \endcode