1
0
mirror of https://gitee.com/drabel/LibQQt.git synced 2025-01-04 10:18:44 +08:00

add webloader, move data persistence to highgrade

This commit is contained in:
tianduanrui 2020-04-14 12:10:20 +08:00
parent d1aa90471e
commit 21f592f94e
6 changed files with 266 additions and 345 deletions

View File

@ -104,7 +104,7 @@ github link: https://github.com/AbelTian/LibQQt
- QQtSerialPort 兼容QSerialPort and QextSerialPort
- [QQtTcpClient](src/network/qqttcpclient.h)、QQtTcpServer、QQtUdpClient、QQtUdpServer
- QQtBluetoothSocket、QQtBluetoothServer +QQtBluetoothManager
- QQtWebAccessManager支持http、ftp等主流协议高并发传输管理cookie和session。
- [QQtWebAccessManager](src/network/qqtwebaccessmanager.h)、[QQtWebLoader](src/network/qqtwebloader.h)支持http、ftp等主流协议高并发传输管理cookie和session。
- [QQtWebSocket](src/network/qqtwebsocketclient.h) 接口
- 一个句柄代表一个和外部通信的节点。
- 报文虚类(接口类) [QQtMessage](src/network/qqtmessage.h)

View File

@ -1,210 +0,0 @@
#include <qqtdatapersistence.h>
#include <QFile>
QQtDataPersistence::QQtDataPersistence ( QObject* parent )
: QObject ( parent )
{
reset_marker();
mDataFormat = JsonData;
mTimerInterval = 1000;
mTimer = new QTimer ( this );
mTimer->setSingleShot ( false );
mTimer->setInterval ( mTimerInterval );
connect ( mTimer, SIGNAL ( timeout() ),
this, SLOT ( slotTimeOut() ) );
}
QQtDataPersistence::~QQtDataPersistence() {}
void QQtDataPersistence::setDataFormat ( QQtDataPersistence::DataFormat format ) { mDataFormat = format; }
QQtDataPersistence::DataFormat QQtDataPersistence::dataFormat() const { return mDataFormat; }
void QQtDataPersistence::setDataFile ( const QString& fileName )
{
mFileName = fileName;
if ( mFileName.isEmpty() )
return;
parseContentToDictionary();
}
QString QQtDataPersistence::dataFile() const { return mFileName; }
void QQtDataPersistence::prepareDataPersistence()
{
if ( mFileName.isEmpty() )
return;
mTimer->start();
}
void QQtDataPersistence::exitDataPersistence()
{
mTimer->stop();
}
void QQtDataPersistence::start()
{
mLock.lockForWrite();
}
QQtDictionary& QQtDataPersistence::dictionary()
{
return mDict;
}
const QQtDictionary& QQtDataPersistence::dictionary() const
{
return mDict;
}
void QQtDataPersistence::stop()
{
marker();
mLock.unlock();
}
int QQtDataPersistence::timerInterval() const { return mTimerInterval; }
void QQtDataPersistence::setTimerInterval ( int millSecond ) { mTimerInterval = millSecond; }
void QQtDataPersistence::slotTimeOut()
{
/*减少写文件marker强制写*/
if ( getMarker() == false )
{
return;
}
//用户设置了marker标记true强制写
setMarker ( false );
QByteArray bytes;
packDictionaryToContent ( bytes );
writeFile ( bytes );
}
void QQtDataPersistence::parseContentToDictionary()
{
QByteArray bytes;
readFile ( bytes );
mLock.lockForWrite();
mDict.clear();
switch ( mDataFormat )
{
case JsonData:
mDict.fromJson ( bytes );
break;
case XmlData:
mDict.fromXML ( bytes );
break;
#ifdef __YAMLSUPPORT__
case YamlData:
mDict.fromYAML ( bytes );
break;
#endif
#ifdef __INICONTENTSUPPORT__
case IniData:
mDict.fromINI ( bytes );
break;
case PropertiesData:
mDict.fromProperties ( bytes );
break;
#endif
#ifdef __QTCSVLIB__
case CSVData:
mDict.fromCSV ( bytes );
break;
#endif
case MaxFormat:
default:
break;
}
mLock.unlock();;
}
void QQtDataPersistence::packDictionaryToContent ( QByteArray& bytes )
{
mLock.lockForRead();
switch ( mDataFormat )
{
case JsonData:
bytes = mDict.toJson ( QJsonDocument::Indented );
break;
case XmlData:
bytes = mDict.toXML ( 4 );
break;
#ifdef __YAMLSUPPORT__
case YamlData:
bytes = mDict.toYAML ( );
break;
#endif
#ifdef __INICONTENTSUPPORT__
case IniData:
bytes = mDict.toINI ( );
break;
case PropertiesData:
bytes = mDict.toProperties ( );
break;
#endif
#ifdef __QTCSVLIB__
case CSVData:
bytes = mDict.toCSV ( );
break;
#endif
case MaxFormat:
default:
break;
}
mLock.unlock();;
}
void QQtDataPersistence::readFile ( QByteArray& bytes )
{
if ( mFileName.isEmpty() )
return;
QFile file ( mFileName );
//pline() << "file:" << mFileName << file.exists();
if ( file.exists() )
file.open ( QFile::ReadOnly );
else
file.open ( QFile::Truncate | QFile::ReadWrite );
bytes = file.readAll();
file.close();
}
void QQtDataPersistence::writeFile ( const QByteArray& bytes )
{
if ( mFileName.isEmpty() )
return;
QFile file ( mFileName );
if ( file.exists() )
file.open ( QFile::WriteOnly );
else
file.open ( QFile::Truncate | QFile::WriteOnly );
file.write ( bytes );
file.close();
}
void QQtDataPersistence::marker ()
{
bMarker = true;
}
void QQtDataPersistence::reset_marker()
{
bMarker = false;
}
void QQtDataPersistence::setMarker ( bool mark )
{
bMarker = mark;
}
bool QQtDataPersistence::getMarker() const
{
return bMarker;
}

View File

@ -1,129 +0,0 @@
#ifndef QQTDATAPERSISTENCE_H
#define QQTDATAPERSISTENCE_H
#include <QObject>
#include <QTimer>
#include <QReadWriteLock>
#include <qqtdictionary.h>
#include <qqt-local.h>
/**
* @brief The QQtDataPersistence class
*
*
*
*
*
*
*
*
*
*
* Timer
*
*
*
*
* 访
* 1.
* 2. Mark时写
*
* 使
* QQtDataPersistence keep_inst;
* keep_inst.PrepareDataPersistence(); //打开持久化功能。once。
*
* keep_inst.start(); //开始持久化数据操作 每次操作都需要开启和关闭
* QQtDictionary& handler = keep_inst.dictionary(); //可以操作的数据句柄
* handler.clear(); //可选:字典数据从新开始。
* handler["key1"]["key2"] = "value1"; //字典发生改变,内部自动保存
* ...
* keep_inst.marker(); // 强制保存!
* keep_inst.stop(); //停止持久化数据操作
*
* keep_inst.ExitDataPersistence(); //退出持久化功能。普通buffer不再保存数据。
*/
class QQTSHARED_EXPORT QQtDataPersistence : public QObject
{
Q_OBJECT
public:
explicit QQtDataPersistence ( QObject* parent = 0 );
virtual ~QQtDataPersistence();
enum DataFormat
{
JsonData,
XmlData,
YamlData,
IniData,
PropertiesData,
CSVData,
MaxFormat
};
//数据格式
void setDataFormat ( DataFormat format = JsonData );
DataFormat dataFormat() const;
//持久化数据文件 [+初始化字典]
void setDataFile ( const QString& fileName );
QString dataFile() const;
//打开数据持久化
void prepareDataPersistence();
//关闭数据持久化
void exitDataPersistence();
//1! 开启
void start();
//2! 操作
QQtDictionary& dictionary();
const QQtDictionary& dictionary() const;
//3! 关闭
void stop();
//持久化数据保存周期 [default:1000ms]
int timerInterval() const;
void setTimerInterval ( int millSecond = 1000 );
private slots:
void slotTimeOut();
protected:
virtual void parseContentToDictionary();
virtual void packDictionaryToContent ( QByteArray& bytes );
//方便函数。文件不存在会创建。
virtual void readFile ( QByteArray& bytes );
virtual void writeFile ( const QByteArray& bytes );
private:
/*设置标记*/
void marker ();
/*重置标记*/
void reset_marker ();
/*设置标记 default: true*/
void setMarker ( bool mark = true );
/*获取标记 default: false*/
bool getMarker() const;
/*一个标记*/
bool bMarker;
private:
QReadWriteLock mLock;
QQtDictionary mDict;
QTimer* mTimer;
int mTimerInterval;
DataFormat mDataFormat;
QString mFileName;
};
#endif // QQTDATAPERSISTENCE_H

View File

@ -0,0 +1,174 @@
#include <qqtwebloader.h>
QQtNetworkReply::QQtNetworkReply ( QObject* parent ) : QNetworkReply ( parent )
{
open ( QIODevice::ReadWrite );
}
QQtNetworkReply::~QQtNetworkReply()
{
close();
}
QQtNetworkReply::QQtNetworkReply ( const QQtNetworkReply& other )
{
*this = ( const QNetworkReply& ) other;
}
QQtNetworkReply& QQtNetworkReply::operator = ( const QNetworkReply& other )
{
setOperation ( other.operation() );
setRequest ( other.request() );
setError ( other.error(), other.errorString() );
setFinished ( other.isFinished() );
setUrl ( other.url() );
for ( int i = ( int ) QNetworkRequest::ContentTypeHeader;
i <= ( int ) QNetworkRequest::ServerHeader; i++ )
{
QNetworkRequest::KnownHeaders ii = ( QNetworkRequest::KnownHeaders ) i;
setHeader ( ii, other.header ( ii ) );
}
QListIterator<QByteArray> itor ( other.rawHeaderList() );
while ( itor.hasNext() )
{
const QByteArray& key = itor.next();
setRawHeader ( key, other.rawHeader ( key ) );
}
for ( int i = ( int ) QNetworkRequest::HttpStatusCodeAttribute;
i <= ( int ) QNetworkRequest::RedirectPolicyAttribute; i++ )
{
QNetworkRequest::Attribute ii = ( QNetworkRequest::Attribute ) i;
setAttribute ( ii, other.attribute ( ii ) );
}
setAttribute ( QNetworkRequest::User, other.attribute ( QNetworkRequest::User ) );
#ifndef QT_NO_SSL
setSslConfiguration ( other.sslConfiguration() );
#endif
return *this;
}
qint64 QQtNetworkReply::readData ( char* data, qint64 maxlen )
{
int size1 = mBytes.size();
if ( maxlen < size1 )
size1 = maxlen;
memcpy ( data, mBytes.constData(), size1 );
mBytes.remove ( 0, size1 );
return size1;
}
qint64 QQtNetworkReply::writeData ( const char* data, qint64 len )
{
mBytes.push_back ( QByteArray ( data, len ) );
return len;
}
void QQtNetworkReply::abort()
{
//
}
QQtWebLoader::QQtWebLoader ( QObject* parent )
: QObject ( parent )
{
mWebAccessManager = new QQtWebAccessManager ( this );
connect ( mWebAccessManager, SIGNAL ( replyFinished ( QQtWebAccessSession* ) ),
this, SLOT ( localReplyFinished ( QQtWebAccessSession* ) ) );
connect ( mWebAccessManager, SIGNAL ( replyTimeOut ( QQtWebAccessSession* ) ),
this, SLOT ( localReplyTimeout ( QQtWebAccessSession* ) ) );
setTimerInterval();
}
QQtWebLoader::~QQtWebLoader() {}
void QQtWebLoader::setTimerInterval ( int millsecond )
{
mWebAccessManager->setTimerInterval ( millsecond );
}
int QQtWebLoader::timerInterval()
{
return mWebAccessManager->timerInterval();
}
QQtWebAccessSession* QQtWebLoader::get ( const QString& url )
{
QNetworkRequest netRequest;
netRequest.setUrl ( QUrl ( url ) ); //地址信息
return get ( netRequest );
}
QQtWebAccessSession* QQtWebLoader::get ( const QNetworkRequest& req )
{
QQtWebAccessSession* session = mWebAccessManager->sendGetRequest ( req );
int millsecond = timerInterval();
//manager的时钟设置会直接影响到session。
//如果用户希望更改某个确定的session的超时可以按照这个思路更改。
//session->getTimer()->setInterval ( millsecond );
//session->getTimer()->start();
millsecond += 1000;
//+1s 给内部超时提供一定的缓冲时间其实就是处理完超时本地的timeout函数解锁。
block1.lock ( millsecond );
return &session1;
}
QQtWebAccessSession* QQtWebLoader::post ( const QString& url, const QByteArray& data )
{
QNetworkRequest netRequest;
netRequest.setUrl ( QUrl ( url ) ); //地址信息
return post ( netRequest, data );
}
QQtWebAccessSession* QQtWebLoader::post ( const QNetworkRequest& req, const QByteArray& data )
{
QQtWebAccessSession* session = mWebAccessManager->sendPostRequest ( req, data );
int millsecond = timerInterval();
//manager的时钟设置会直接影响到session。
//如果用户希望更改某个确定的session的超时可以按照这个思路更改。
//session->getTimer()->setInterval ( millsecond );
//session->getTimer()->start();
millsecond += 1000;
//+1s 给内部超时提供一定的缓冲时间其实就是处理完超时本地的timeout函数解锁。
block1.lock ( millsecond );
return &session1;
}
void QQtWebLoader::localReplyFinished ( QQtWebAccessSession* session )
{
//把session信息保存到本地才能保留下来。
reply1 = * ( session->getWebAccessReply() );
reply1.write ( session->getWebAccessReply()->readAll() );
session1.setWebAccessSessionName ( session->getWebAccessSessionName() );
session1.setWebAccessUrl ( session->getWebAccessUrl() );
session1.getTimer()->setInterval ( session->getTimer()->interval() );
session1.setWebAccessReply ( &reply1 );
session1.webAccessRequest() = session->webAccessRequest();
block1.unlock();
}
void QQtWebLoader::localReplyTimeout ( QQtWebAccessSession* session )
{
reply1 = * ( session->getWebAccessReply() );
//reply1.write ( session->getWebAccessReply()->readAll() );//???
session1.setWebAccessSessionName ( session->getWebAccessSessionName() );
session1.setWebAccessUrl ( session->getWebAccessUrl() );
session1.getTimer()->setInterval ( session->getTimer()->interval() );
session1.setWebAccessReply ( &reply1 );
session1.webAccessRequest() = session->webAccessRequest();
block1.unlock();
}

View File

@ -0,0 +1,88 @@
#ifndef QQTWEBLOADER_H
#define QQTWEBLOADER_H
#include <QObject>
#include <qqtwebaccessmanager.h>
#include <qqt-local.h>
class QQTSHARED_EXPORT QQtNetworkReply : public QNetworkReply
{
Q_OBJECT
public:
explicit QQtNetworkReply ( QObject* parent = 0 );
virtual ~QQtNetworkReply();
QQtNetworkReply ( const QQtNetworkReply& other );
QQtNetworkReply& operator = ( const QNetworkReply& other );
// QIODevice interface
protected:
virtual qint64 readData ( char* data, qint64 maxlen ) override;
// QIODevice interface
protected:
virtual qint64 writeData ( const char* data, qint64 len ) override;
// QNetworkReply interface
public slots:
virtual void abort() override;
private:
QByteArray mBytes;
};
/**
* @brief The QQtWebLoader class
* 线使GUI
*
* Http请求工具线
* getpost
*
* HTTP请求
*/
class QQTSHARED_EXPORT QQtWebLoader : public QObject
{
Q_OBJECT
public:
explicit QQtWebLoader ( QObject* parent = 0 );
virtual ~QQtWebLoader();
QQtWebAccessManager* manager() {
return mWebAccessManager;
}
//返回的session里面的reply是QQtNetworkReply。
//get之后可以修改这一个session的超时不可以。
QQtWebAccessSession* get ( const QString& url );
//manager提供接口修改request用户可以在session里修改不可以。
//这个接口提供给用户manager没修改request的部分用户可以改。
QQtWebAccessSession* get ( const QNetworkRequest& req );
QQtWebAccessSession* post ( const QString& url, const QByteArray& data );
QQtWebAccessSession* post ( const QNetworkRequest& req, const QByteArray& data );
//全局session有效
void setTimerInterval ( int millsecond = 5000 );
int timerInterval();
/*
*
*/
protected slots:
void localReplyFinished ( QQtWebAccessSession* session );
void localReplyTimeout ( QQtWebAccessSession* session );
protected:
private:
QQtWebAccessManager* mWebAccessManager;
QQtWebAccessSession session1;
QQtNetworkReply reply1;
QQtBlock block1;
};
#endif // QQTWEBLOADER_H

View File

@ -367,6 +367,9 @@ contains (DEFINES, __NETWORKSUPPORT__) {
contains (DEFINES, __WEBACCESSSUPPORT__) {
SOURCES += $$PWD/network/qqtwebaccessmanager.cpp
HEADERS += $$PWD/network/qqtwebaccessmanager.h
SOURCES += $$PWD/network/qqtwebloader.cpp
HEADERS += $$PWD/network/qqtwebloader.h
}
}
@ -690,11 +693,6 @@ contains (DEFINES, __HIGHGRADE__) {
HEADERS += \
$$PWD/highgrade/qqtsingletonapplication.h
}
SOURCES += \
$$PWD/highgrade/qqtdatapersistence.cpp
HEADERS += \
$$PWD/highgrade/qqtdatapersistence.h
}
include ($$PWD/qqt_3rdparty.pri)