#ifndef CLIENTCORE_H #define CLIENTCORE_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class ClientCore : public QObject { Q_OBJECT public: ClientCore(QObject* parent, asio::io_context& ioContext); ~ClientCore(); public slots: void Disconnect(); public slots: void DoConnect(const QString& ip, quint16 port); public: void Instance(); asio::awaitable Connect(const QString& ip, quint16 port); bool IsConnect(); const asio::any_io_executor& get_executor(); template asio::awaitable Send(const T& info, FrameBufferType type, const QString& tid) { auto f = GetBuffer(info, type, tid); co_return co_await Send(f); } template QSharedPointer GetBuffer(const T& info, FrameBufferType type, const QString& tid) { auto f = QSharedPointer::create(); f->tid = tid; f->data = infoPack(info); f->type = type; return f; } static bool syncInvoke(ClientCore* context, QSharedPointer frame) { bool result = false; try { std::future fut = asio::co_spawn( context->get_executor(), [context, frame]() -> asio::awaitable { co_return co_await context->Send(frame); }, asio::use_future); result = fut.get(); } catch (const std::exception& ex) { // std::cerr << e.what() << '\n'; } // bool success = QMetaObject::invokeMethod(context, "SendFrame", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, // result), // Q_ARG(QSharedPointer, frame)); // if (!success) { // return false; // } return result; } signals: void sigDisconnect(); void sigPath(const QString& path, const QVector& drivers); void sigClients(const InfoClientVec& clients); void sigFiles(const DirFileInfoVec& files); void sigReqSend(QSharedPointer frame); void sigReqDown(QSharedPointer frame); void sigTransDone(QSharedPointer frame); void sigCanSend(QSharedPointer frame); void sigCanotSend(QSharedPointer frame); void sigCanotDown(QSharedPointer frame); void sigCanDown(QSharedPointer frame); void sigFileBuffer(QSharedPointer frame); void sigTransFailed(QSharedPointer frame); void sigFileInfo(QSharedPointer frame); void sigOffline(QSharedPointer frame); void sigYourId(QSharedPointer frame); void sigMsgAsk(QSharedPointer frame); void sigMsgAnswer(QSharedPointer frame); void sigFlowBack(QSharedPointer frame); void sigTransInterrupt(QSharedPointer frame); signals: void conSuccess(); void connecting(); void conFailed(); private: void onReadyRead(); void onDisconnected(); asio::awaitable handleAsk(QSharedPointer frame); private: asio::awaitable UseFrame(QSharedPointer frame); public: void SetRemoteID(const QString& id); QString GetRemoteID(); QString GetOwnID(); void pushID(const QString& id); void popID(const QString& id); public: QMutex conMutex_; QString ownID_; // 这是被动发送时,对方ID。 QReadWriteLock rwIDLock_; QVector remoteIDs_; // 这是主动通信时的对方ID。 QString remoteID_; QMutex sockMut_; QByteArray recvBuffer_; bool connected_{false}; LocalFile localFile_; // asio变更 private: asio::io_context& ioContext_; asio::ip::tcp::socket mSocket_; std::array mBuffer_; std::mutex frameMutex_; std::queue> frameQueue_; private: asio::awaitable Send(QSharedPointer frame); asio::awaitable Send(const char* data, size_t size); asio::awaitable recvData(); }; // Socket Worker Thread class SocketWorker : public QThread { Q_OBJECT public: SocketWorker(ClientCore* core, QObject* parent = nullptr); ~SocketWorker(); protected: void run() override; private: ClientCore* core_{}; }; // 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_{}; }; 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 frame) = 0; protected: bool isRun_; bool isAlreadyInter_; ClientCore* cli_{}; }; #endif // CLIENTCORE_H