2025-06-16 23:41:35 +08:00
|
|
|
#ifndef CLIENTCORE_H
|
2025-06-14 23:25:16 +08:00
|
|
|
#define CLIENTCORE_H
|
|
|
|
|
|
2025-06-15 14:31:54 +08:00
|
|
|
#include <InfoClient.h>
|
|
|
|
|
#include <InfoDirFile.h>
|
2025-06-15 23:13:30 +08:00
|
|
|
#include <InfoMsg.h>
|
|
|
|
|
#include <InfoPack.hpp>
|
|
|
|
|
#include <LocalFile.h>
|
2025-06-14 23:25:16 +08:00
|
|
|
#include <Protocol.h>
|
|
|
|
|
#include <QDataStream>
|
|
|
|
|
#include <QHostAddress>
|
|
|
|
|
#include <QMutex>
|
|
|
|
|
#include <QMutexLocker>
|
2025-06-19 11:59:32 +08:00
|
|
|
#include <QQueue>
|
2025-11-16 10:48:09 +08:00
|
|
|
#include <QReadWriteLock>
|
2025-06-14 23:25:16 +08:00
|
|
|
#include <QThread>
|
2025-06-16 20:06:49 +08:00
|
|
|
#include <array>
|
2026-03-24 16:53:06 +08:00
|
|
|
#include <asio.hpp>
|
|
|
|
|
#include <queue>
|
2025-06-14 23:25:16 +08:00
|
|
|
|
|
|
|
|
class ClientCore : public QObject
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
2026-03-24 16:53:06 +08:00
|
|
|
ClientCore(QObject* parent, asio::io_context& ioContext);
|
2025-06-14 23:25:16 +08:00
|
|
|
~ClientCore();
|
|
|
|
|
|
2025-06-25 10:54:04 +08:00
|
|
|
public slots:
|
2025-06-26 22:59:58 +08:00
|
|
|
void Disconnect();
|
|
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
void DoConnect(const QString& ip, quint16 port);
|
2025-06-25 10:54:04 +08:00
|
|
|
|
2025-06-14 23:25:16 +08:00
|
|
|
public:
|
2025-06-20 14:33:51 +08:00
|
|
|
void Instance();
|
2026-03-24 17:20:21 +08:00
|
|
|
asio::awaitable<bool> Connect(const QString& ip, quint16 port);
|
2025-06-25 17:06:30 +08:00
|
|
|
bool IsConnect();
|
2026-03-24 16:53:06 +08:00
|
|
|
const asio::any_io_executor& get_executor();
|
|
|
|
|
template <typename T> asio::awaitable<bool> Send(const T& info, FrameBufferType type, const QString& tid)
|
2025-06-19 11:59:32 +08:00
|
|
|
{
|
|
|
|
|
auto f = GetBuffer<T>(info, type, tid);
|
2026-03-24 16:53:06 +08:00
|
|
|
co_return co_await Send(f);
|
2025-06-19 11:59:32 +08:00
|
|
|
}
|
|
|
|
|
template <typename T> QSharedPointer<FrameBuffer> GetBuffer(const T& info, FrameBufferType type, const QString& tid)
|
2025-06-15 23:13:30 +08:00
|
|
|
{
|
|
|
|
|
auto f = QSharedPointer<FrameBuffer>::create();
|
|
|
|
|
f->tid = tid;
|
|
|
|
|
f->data = infoPack<T>(info);
|
|
|
|
|
f->type = type;
|
2025-06-19 11:59:32 +08:00
|
|
|
return f;
|
2025-06-15 23:13:30 +08:00
|
|
|
}
|
2025-06-25 10:54:04 +08:00
|
|
|
static bool syncInvoke(ClientCore* context, QSharedPointer<FrameBuffer> frame)
|
2025-06-19 11:59:32 +08:00
|
|
|
{
|
2025-06-25 10:54:04 +08:00
|
|
|
bool result = false;
|
2026-03-24 16:53:06 +08:00
|
|
|
try {
|
|
|
|
|
std::future<bool> fut = asio::co_spawn(
|
|
|
|
|
context->get_executor(), [context, frame]() -> asio::awaitable<bool> { co_return co_await context->Send(frame); },
|
|
|
|
|
asio::use_future);
|
|
|
|
|
result = fut.get();
|
|
|
|
|
} catch (const std::exception& ex) {
|
|
|
|
|
// std::cerr << e.what() << '\n';
|
2025-06-25 10:54:04 +08:00
|
|
|
}
|
2026-03-24 16:53:06 +08:00
|
|
|
|
|
|
|
|
// bool success = QMetaObject::invokeMethod(context, "SendFrame", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool,
|
|
|
|
|
// result),
|
|
|
|
|
// Q_ARG(QSharedPointer<FrameBuffer>, frame));
|
|
|
|
|
// if (!success) {
|
|
|
|
|
// return false;
|
|
|
|
|
// }
|
2025-06-25 10:54:04 +08:00
|
|
|
return result;
|
2025-06-19 11:59:32 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
signals:
|
|
|
|
|
void sigDisconnect();
|
2025-11-11 08:52:09 +08:00
|
|
|
void sigPath(const QString& path, const QVector<QString>& drivers);
|
2025-06-19 15:37:39 +08:00
|
|
|
void sigClients(const InfoClientVec& clients);
|
|
|
|
|
void sigFiles(const DirFileInfoVec& files);
|
|
|
|
|
void sigReqSend(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigReqDown(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigTransDone(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigCanSend(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigCanotSend(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigCanotDown(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigCanDown(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigFileBuffer(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigTransFailed(QSharedPointer<FrameBuffer> frame);
|
2025-06-20 09:45:39 +08:00
|
|
|
void sigFileInfo(QSharedPointer<FrameBuffer> frame);
|
2025-10-20 16:40:52 +08:00
|
|
|
void sigOffline(QSharedPointer<FrameBuffer> frame);
|
2025-10-21 09:48:20 +08:00
|
|
|
void sigYourId(QSharedPointer<FrameBuffer> frame);
|
2025-11-05 10:57:40 +08:00
|
|
|
void sigMsgAsk(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
void sigMsgAnswer(QSharedPointer<FrameBuffer> frame);
|
2025-11-09 11:53:59 +08:00
|
|
|
void sigFlowBack(QSharedPointer<FrameBuffer> frame);
|
2025-11-09 14:26:39 +08:00
|
|
|
void sigTransInterrupt(QSharedPointer<FrameBuffer> frame);
|
2025-06-14 23:25:16 +08:00
|
|
|
|
2025-06-20 14:33:51 +08:00
|
|
|
signals:
|
|
|
|
|
void conSuccess();
|
|
|
|
|
void connecting();
|
|
|
|
|
void conFailed();
|
|
|
|
|
|
2025-06-14 23:44:13 +08:00
|
|
|
private:
|
|
|
|
|
void onReadyRead();
|
|
|
|
|
void onDisconnected();
|
2026-03-24 16:53:06 +08:00
|
|
|
asio::awaitable<void> handleAsk(QSharedPointer<FrameBuffer> frame);
|
2025-06-14 23:25:16 +08:00
|
|
|
|
2025-06-14 23:44:13 +08:00
|
|
|
private:
|
2026-03-24 16:53:06 +08:00
|
|
|
asio::awaitable<void> UseFrame(QSharedPointer<FrameBuffer> frame);
|
2025-06-15 14:31:54 +08:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void SetRemoteID(const QString& id);
|
|
|
|
|
QString GetRemoteID();
|
2025-06-18 14:53:56 +08:00
|
|
|
QString GetOwnID();
|
2025-11-09 14:26:39 +08:00
|
|
|
void pushID(const QString& id);
|
|
|
|
|
void popID(const QString& id);
|
2025-06-14 23:25:16 +08:00
|
|
|
|
2025-06-14 23:44:13 +08:00
|
|
|
public:
|
|
|
|
|
QMutex conMutex_;
|
2025-06-15 20:37:25 +08:00
|
|
|
QString ownID_;
|
2025-11-09 14:26:39 +08:00
|
|
|
|
|
|
|
|
// 这是被动发送时,对方ID。
|
|
|
|
|
QReadWriteLock rwIDLock_;
|
|
|
|
|
QVector<QString> remoteIDs_;
|
|
|
|
|
|
|
|
|
|
// 这是主动通信时的对方ID。
|
2025-06-14 23:25:16 +08:00
|
|
|
QString remoteID_;
|
2025-06-17 11:48:13 +08:00
|
|
|
|
|
|
|
|
QMutex sockMut_;
|
2025-06-14 23:25:16 +08:00
|
|
|
QByteArray recvBuffer_;
|
2025-06-14 23:44:13 +08:00
|
|
|
|
2025-06-25 10:54:04 +08:00
|
|
|
bool connected_{false};
|
2025-06-15 23:13:30 +08:00
|
|
|
LocalFile localFile_;
|
2026-03-24 16:53:06 +08:00
|
|
|
|
|
|
|
|
// asio变更
|
|
|
|
|
private:
|
|
|
|
|
asio::io_context& ioContext_;
|
|
|
|
|
asio::ip::tcp::socket mSocket_;
|
|
|
|
|
std::array<char, CHUNK_BUF_SIZE> mBuffer_;
|
|
|
|
|
std::mutex frameMutex_;
|
|
|
|
|
std::queue<QSharedPointer<FrameBuffer>> frameQueue_;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
asio::awaitable<bool> Send(QSharedPointer<FrameBuffer> frame);
|
|
|
|
|
asio::awaitable<bool> Send(const char* data, size_t size);
|
|
|
|
|
asio::awaitable<void> recvData();
|
2025-06-14 23:25:16 +08:00
|
|
|
};
|
|
|
|
|
|
2025-06-25 17:06:30 +08:00
|
|
|
// Socket Worker Thread
|
2025-06-19 11:59:32 +08:00
|
|
|
class SocketWorker : public QThread
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
SocketWorker(ClientCore* core, QObject* parent = nullptr);
|
|
|
|
|
~SocketWorker();
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void run() override;
|
|
|
|
|
|
|
|
|
|
private:
|
2025-06-19 15:37:39 +08:00
|
|
|
ClientCore* core_{};
|
2025-06-19 11:59:32 +08:00
|
|
|
};
|
|
|
|
|
|
2025-06-25 17:06:30 +08:00
|
|
|
// HeatBeat to Server
|
|
|
|
|
class HeatBeat : public QThread
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
HeatBeat(ClientCore* core, QObject* parent = nullptr);
|
|
|
|
|
~HeatBeat() override;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void Stop();
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
void run() override;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
bool isRun_{false};
|
|
|
|
|
ClientCore* core_{};
|
|
|
|
|
};
|
|
|
|
|
|
2025-11-16 10:48:09 +08:00
|
|
|
class WaitThread : public QThread
|
|
|
|
|
{
|
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
WaitThread(QObject* parent = nullptr);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void SetClient(ClientCore* cli);
|
|
|
|
|
bool IsQuit() const;
|
|
|
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
|
void sigCheckOver();
|
|
|
|
|
|
|
|
|
|
public Q_SLOTS:
|
|
|
|
|
virtual void interrupCheck();
|
|
|
|
|
virtual void recvFrame(QSharedPointer<FrameBuffer> frame) = 0;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
bool isRun_;
|
|
|
|
|
bool isAlreadyInter_;
|
|
|
|
|
ClientCore* cli_{};
|
|
|
|
|
};
|
|
|
|
|
|
2025-06-14 23:25:16 +08:00
|
|
|
#endif // CLIENTCORE_H
|