添加文件夹传输进度更新。
This commit is contained in:
@@ -142,6 +142,10 @@ void ClientCore::handleAsk(QSharedPointer<FrameBuffer> frame)
|
||||
}
|
||||
return;
|
||||
}
|
||||
// 这个请求的处理可能是耗时的,需要开线程处理。
|
||||
if (msg.command == STRMSG_AC_ALL_DIRFILES) {
|
||||
msg.command = STRMSG_AC_ANSWER_ALL_DIRFILES;
|
||||
}
|
||||
// 未知信息
|
||||
qWarning() << QString(tr("未知询问信息类型:%1")).arg(msg.command);
|
||||
}
|
||||
@@ -413,4 +417,97 @@ void WaitThread::interrupCheck()
|
||||
isAlreadyInter_ = true;
|
||||
emit sigCheckOver();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WaitOper::WaitOper(QObject* parent) : WaitThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void WaitOper::run()
|
||||
{
|
||||
isAlreadyInter_ = false;
|
||||
infoMsg_.msg = STR_NONE;
|
||||
isRun_ = true;
|
||||
recvMsg_ = false;
|
||||
|
||||
InfoMsg msg;
|
||||
msg.command = sendStrType_;
|
||||
msg.fromPath = stra_;
|
||||
msg.toPath = strb_;
|
||||
msg.type = type_;
|
||||
|
||||
auto f = cli_->GetBuffer<InfoMsg>(msg, FBT_MSGINFO_ASK, cli_->GetRemoteID());
|
||||
if (!ClientCore::syncInvoke(cli_, f)) {
|
||||
auto errMsg = QString(tr("向%1发送%2请求失败。")).arg(cli_->GetRemoteID()).arg(sendStrType_);
|
||||
emit sigCheckOver();
|
||||
qCritical() << errMsg;
|
||||
return;
|
||||
}
|
||||
while (isRun_) {
|
||||
QThread::msleep(1);
|
||||
if (isAlreadyInter_) {
|
||||
qInfo() << tr("线程中断文件操作等待......");
|
||||
return;
|
||||
}
|
||||
if (!recvMsg_) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
isAlreadyInter_ = true;
|
||||
emit sigCheckOver();
|
||||
auto n = QString(tr("向%1的请求%2处理结束。")).arg(cli_->GetRemoteID()).arg(sendStrType_);
|
||||
qInfo() << n;
|
||||
}
|
||||
|
||||
void WaitOper::SetType(const QString& sendType, const QString& ansType)
|
||||
{
|
||||
sendStrType_ = sendType;
|
||||
ansStrType_ = ansType;
|
||||
}
|
||||
|
||||
void WaitOper::SetPath(const QString& stra, const QString& strb, const QString& type)
|
||||
{
|
||||
stra_ = stra;
|
||||
strb_ = strb;
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
InfoMsg WaitOper::GetMsg() const
|
||||
{
|
||||
return infoMsg_;
|
||||
}
|
||||
|
||||
void WaitOper::interrupCheck()
|
||||
{
|
||||
qWarning() << QString(tr("中断请求处理%1......")).arg(sendStrType_);
|
||||
WaitThread::interrupCheck();
|
||||
}
|
||||
|
||||
void WaitOper::recvFrame(QSharedPointer<FrameBuffer> frame)
|
||||
{
|
||||
InfoMsg info = infoUnpack<InfoMsg>(frame->data);
|
||||
if (info.command == ansStrType_) {
|
||||
infoMsg_ = info;
|
||||
recvMsg_ = true;
|
||||
return;
|
||||
}
|
||||
auto n = tr("收到未知Oper的回复信息:") + info.command;
|
||||
qInfo() << n;
|
||||
}
|
||||
|
||||
WaitOperOwn::WaitOperOwn(QObject* parent) : WaitThread(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void WaitOperOwn::run()
|
||||
{
|
||||
if (func_) {
|
||||
func_();
|
||||
}
|
||||
emit sigOver();
|
||||
}
|
||||
|
||||
void WaitOperOwn::recvFrame(QSharedPointer<FrameBuffer> frame)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public:
|
||||
LocalFile localFile_;
|
||||
};
|
||||
|
||||
// Socket Worker Thread
|
||||
// 工作线程。
|
||||
class SocketWorker : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -139,7 +139,7 @@ private:
|
||||
ClientCore* core_{};
|
||||
};
|
||||
|
||||
// HeatBeat to Server
|
||||
// 心跳包线程。
|
||||
class HeatBeat : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -159,6 +159,7 @@ private:
|
||||
ClientCore* core_{};
|
||||
};
|
||||
|
||||
// 耗时操作线程基本框架。
|
||||
class WaitThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -183,4 +184,48 @@ protected:
|
||||
ClientCore* cli_{};
|
||||
};
|
||||
|
||||
// 等待对方应答的等待线程。
|
||||
class WaitOper : public WaitThread
|
||||
{
|
||||
public:
|
||||
WaitOper(QObject* parent = nullptr);
|
||||
|
||||
public:
|
||||
void run() override;
|
||||
void SetType(const QString& sendType, const QString& ansType);
|
||||
void SetPath(const QString& stra, const QString& strb, const QString& type);
|
||||
InfoMsg GetMsg() const;
|
||||
void interrupCheck() override;
|
||||
void recvFrame(QSharedPointer<FrameBuffer> frame) override;
|
||||
|
||||
private:
|
||||
bool recvMsg_{};
|
||||
InfoMsg infoMsg_{};
|
||||
QString sendStrType_{};
|
||||
QString ansStrType_{};
|
||||
QString stra_;
|
||||
QString strb_;
|
||||
QString type_;
|
||||
};
|
||||
|
||||
// 等待自己耗时操作的线程。
|
||||
class WaitOperOwn : public WaitThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
WaitOperOwn(QObject* parent = nullptr);
|
||||
|
||||
signals:
|
||||
void sigOver();
|
||||
|
||||
public:
|
||||
void run() override;
|
||||
void recvFrame(QSharedPointer<FrameBuffer> frame) override;
|
||||
|
||||
public:
|
||||
InfoMsg infoMsg_{};
|
||||
std::function<void()> func_;
|
||||
};
|
||||
|
||||
#endif // CLIENTCORE_H
|
||||
@@ -398,7 +398,25 @@ void FileTrans::SendFile(const QSharedPointer<DoTransTask>& task)
|
||||
|
||||
QMutexLocker locker(&sthMut_);
|
||||
upTasks_[task->task.localId] = sendThread;
|
||||
sendThread->run();
|
||||
|
||||
// 2026-03-24 找了一个可能卡顿的原因。
|
||||
/*
|
||||
在 Qt 的 QThread类中,start()和 run()有本质区别:
|
||||
|
||||
start()- 创建新线程 sendThread->start(); // ✅ 正确
|
||||
|
||||
启动一个新线程,在新线程中执行 run()方法,线程有自己的事件循环(如果调用 exec())
|
||||
|
||||
自动处理线程同步和资源管理信号/槽可以跨线程工作
|
||||
|
||||
run()- 只是普通方法调用 sendThread->run(); // ❌ 错误用法
|
||||
|
||||
在当前线程中直接调用这个方法,没有创建新线程阻塞当前线程直到 run()返回
|
||||
|
||||
对象的信号/槽仍然在原始线程上下文中
|
||||
*/
|
||||
// sendThread->run();
|
||||
sendThread->start();
|
||||
}
|
||||
|
||||
SendThread::SendThread(ClientCore* clientCore) : cliCore_(clientCore)
|
||||
@@ -442,7 +460,7 @@ void SendThread::run()
|
||||
}
|
||||
task_->tranSize += frame->data.size();
|
||||
// 关键点:这里不调用,无法中途收到别人发的数据。
|
||||
QCoreApplication::processEvents();
|
||||
// QCoreApplication::processEvents();
|
||||
}
|
||||
qInfo() << QString(tr("结束发送文件:%1")).arg(task_->file.fileName());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user