From b877a9e32476e41728afc222dd339d6786ce7c94 Mon Sep 17 00:00:00 2001 From: Joy1024 <412555203@qq.com> Date: Thu, 8 Aug 2024 18:18:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96`=E6=8E=A5=E5=8F=97=E6=96=87?= =?UTF-8?q?=E4=BB=B6`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib/messenger/IMFile.cpp | 102 ++++++++++++++++++++++------ src/lib/messenger/IMFile.h | 20 +++++- src/lib/messenger/IMJingle.cpp | 37 +--------- src/lib/messenger/IMJingle.h | 5 +- src/lib/messenger/IMJingleSession.h | 1 + 5 files changed, 105 insertions(+), 60 deletions(-) diff --git a/src/lib/messenger/IMFile.cpp b/src/lib/messenger/IMFile.cpp index 95928f10..36f654c5 100644 --- a/src/lib/messenger/IMFile.cpp +++ b/src/lib/messenger/IMFile.cpp @@ -42,10 +42,11 @@ QDebug& operator<<(QDebug& debug, const File& f) { } IMFileSession::IMFileSession(const QString& sId, + Jingle::Session* session_, const IMPeerId& peerId, IMFile* sender_, File* file) - : sId(sId), target(peerId), sender(sender_), file(file) { + : sId(sId), target(peerId), sender(sender_), file(file), session(session_) { qDebug() << __func__ << "Create file task:" << sId; task = std::make_unique(target.toString(), file, sender); @@ -58,7 +59,6 @@ IMFileSession::IMFileSession(const QString& sId, connect(task.get(), &IMFileTask::fileAbort, [&](const QString& m_friendId, const File& m_file, int m_sentBytes) { - // emit sendFileAbort(qstring(m_friendId.bare()), m_file, m_sentBytes); for (auto h : sender->getHandlers()) { h->onFileSendAbort(m_friendId, m_file, m_sentBytes); } @@ -70,7 +70,6 @@ IMFileSession::IMFileSession(const QString& sId, h->onFileSendError(m_friendId, m_file, m_sentBytes); } }); - task->start(); } void IMFileSession::stop() { @@ -80,9 +79,16 @@ void IMFileSession::stop() { } } +void IMFileSession::start() { + if (task && !task->isRunning()) { + task->start(); + } +} + IMFile::IMFile(IM* im, QObject* parent) : IMJingle(im, parent) { qRegisterMetaType("File"); - + auto client = im->getClient(); + client->registerIqHandler(this, ExtIBB); // jingle = IMJingle::getInstance(); // jingle->setFileHandlers(&fileHandlers); @@ -216,10 +222,12 @@ void IMFile::rejectFileRequest(const QString& friendId, const QString& sId) { } void IMFile::acceptFileRequest(const QString& friendId, const File& file) { - qDebug() << __func__ << file.name << file.sId << file.id; + qDebug() << __func__ << file.name; + qDebug() << __func__ << "sId:" << file.sId; + qDebug() << __func__ << "fileId:" << file.id; - auto* ws = findSession(file.sId); - if (!ws) { + auto session = m_fileSessionMap.value(file.sId); + if (!session) { qWarning() << "Unable to find session sId:" << file.sId; return; } @@ -239,7 +247,8 @@ void IMFile::acceptFileRequest(const QString& friendId, const File& file) { pluginList.emplace_back(ibb); auto c = new Jingle::Content("file", pluginList); - ws->getSession()->sessionAccept(c); + auto js = session->getJingleSession(); + if (js) js->sessionAccept(c); } void IMFile::finishFileRequest(const QString& friendId, const QString& sId) { @@ -318,7 +327,7 @@ bool IMFile::sendFileToResource(const JID& jid, const File& file) { } // 对方接收文件 -void IMFile::sessionOnAccept(const QString& sId, const IMPeerId& peerId) { +void IMFile::sessionOnAccept(const QString& sId, Jingle::Session* session, const IMPeerId& peerId) { IMFileSession* sess = m_fileSessionMap.value(sId); if (sess) { qWarning() << "File session is existing, the sId is" << sId; @@ -327,7 +336,8 @@ void IMFile::sessionOnAccept(const QString& sId, const IMPeerId& peerId) { // 创建session for (auto& file : m_waitSendFiles) { - auto s = new IMFileSession(sId, peerId, this, &file); + auto s = new IMFileSession(sId, session, peerId, this, &file); + s->start(); m_fileSessionMap.insert(sId, s); } } @@ -338,12 +348,12 @@ void IMFile::sessionOnTerminate(const QString& sId, const IMPeerId& peerId) { qWarning() << "File session is no existing, the sId is" << sId; return; } - m_fileSessionMap.remove(sId); delete sess; } void IMFile::sessionOnInitiate(const QString& sId, + Jingle::Session* session, const Jingle::Session::Jingle* jingle, const IMPeerId& peerId) { qDebug() << __func__ << "receive file:" << sId; @@ -360,21 +370,22 @@ void IMFile::sessionOnInitiate(const QString& sId, // auto sId = qstring(session->sid()); qDebug() << "receive file:" << id << sId; - File file0 = {.id = id, - .sId = sId, - .name = qstring(f.name), - .path = {}, - .size = (quint64)f.size, - .status = FileStatus::INITIALIZING, - .direction = FileDirection::RECEIVING}; - qDebug() << "receive file:" << file0.toString(); + File* file0 = new File{.id = id, + .sId = sId, + .name = qstring(f.name), + .path = {}, + .size = (quint64)f.size, + .status = FileStatus::INITIALIZING, + .direction = FileDirection::RECEIVING}; + qDebug() << "receive file:" << file0->sId; for (auto h : fileHandlers) { - h->onFileRequest(peerId.toFriendId(), file0); + h->onFileRequest(peerId.toFriendId(), *file0); } - // emit receiveFileRequest(peerId.toFriendId(), file); + // 创建session + auto s = new IMFileSession(sId, session, peerId, this, file0); + m_fileSessionMap.insert(sId, s); } - // isFile = true; } break; } @@ -384,5 +395,52 @@ void IMFile::sessionOnInitiate(const QString& sId, } } +bool IMFile::handleIq(const IQ& iq) { + const auto* ibb = iq.findExtension(ExtIBB); + if (!ibb) { + return false; + } + + IMContactId friendId(qstring(iq.from().bare())); + qDebug() << __func__ << QString("IBB stream id:%1").arg(qstring(ibb->sid())); + + switch (ibb->type()) { + case InBandBytestream::IBBOpen: { + qDebug() << __func__ << QString("Open"); + break; + } + case InBandBytestream::IBBData: { + auto sId = qstring(ibb->sid()); + + qDebug() << __func__ << QString("Data seq:%1").arg(ibb->seq()); + for (auto h : fileHandlers) { + h->onFileRecvChunk(friendId.toString(), sId, ibb->seq(), ibb->data()); + } + + break; + } + case InBandBytestream::IBBClose: { + qDebug() << __func__ << QString("Close"); + auto sId = qstring(ibb->sid()); + // auto ss = m_fileSessionMap.value(sId); + for (auto k : m_fileSessionMap.keys()) { + auto ss = m_fileSessionMap.value(k); + ss->getJingleSession()->sessionTerminate( + new Session::Reason(Session::Reason::Success)); + } + for (auto h : fileHandlers) { + h->onFileRecvFinished(friendId.toString(), sId); + } + break; + } + default: { + } + } + + IQ riq(IQ::IqType::Result, iq.from(), iq.id()); + _im->getClient()->send(riq); + return true; +} + } // namespace messenger } // namespace lib diff --git a/src/lib/messenger/IMFile.h b/src/lib/messenger/IMFile.h index 024841aa..40c1b020 100644 --- a/src/lib/messenger/IMFile.h +++ b/src/lib/messenger/IMFile.h @@ -32,9 +32,16 @@ class IM; class IMFileSession : public QObject, IMJingSession { Q_OBJECT public: - IMFileSession(const QString& sId, const IMPeerId& peerId, IMFile* sender, File* file); + IMFileSession(const QString& sId, + Jingle::Session* session_, + const IMPeerId& peerId, + IMFile* sender, + File* file); + void start(); void stop(); + Session* getJingleSession() { return session; } + protected: private: QString sId; @@ -43,9 +50,13 @@ class IMFileSession : public QObject, IMJingSession { // 对方 IMPeerId target; + // 自己 QString self; + // session + Session* session; + std::unique_ptr task; }; @@ -70,13 +81,18 @@ class IMFile : public IMJingle { // 收到对方发起 void sessionOnInitiate(const QString& sId, + Jingle::Session* session, const Jingle::Session::Jingle* jingle, const IMPeerId& peerId); // 对方接受 - void sessionOnAccept(const QString& sId, const IMPeerId& peerId) override; + void sessionOnAccept(const QString& sId, + Jingle::Session* session, + const IMPeerId& peerId) override; // 对方终止 void sessionOnTerminate(const QString& sId, const IMPeerId& peerId) override; + bool handleIq(const IQ& iq) override; + /** * 启动文件发送任务 * @param session diff --git a/src/lib/messenger/IMJingle.cpp b/src/lib/messenger/IMJingle.cpp index 933a1047..83729f85 100644 --- a/src/lib/messenger/IMJingle.cpp +++ b/src/lib/messenger/IMJingle.cpp @@ -40,7 +40,6 @@ IMJingle::IMJingle(IM* im, QObject* parent) : QObject(parent), _im(im) { auto client = _im->getClient(); client->registerMessageHandler(this); - client->registerIqHandler(this, ExtIBB); client->registerStanzaExtension(new Jingle::JingleMessage()); // jingle session @@ -342,7 +341,7 @@ void IMJingle::doSessionInitiate(Jingle::Session* session, auto sid = qstring(session->sid()); qDebug() << __func__ << "sId:" << sid << "peerId:" << peerId.toString(); - sessionOnInitiate(sid, jingle, peerId); + sessionOnInitiate(sid, session, jingle, peerId); // bool isFile = false; // for (auto p : jingle->plugins()) { @@ -476,7 +475,7 @@ void IMJingle::doSessionAccept(Jingle::Session* session, const IMPeerId& peerId) { auto sid = qstring(jingle->sid()); qDebug() << __func__ << sid << "peerId:" << peerId.toString(); - sessionOnAccept(sid, peerId); + sessionOnAccept(sid, session, peerId); } void IMJingle::doSessionInfo(const Session::Jingle* jingle, const IMPeerId& friendId) { @@ -637,39 +636,7 @@ void IMJingle::retractJingleMessage(const QString& friendId, const QString& call } bool IMJingle::handleIq(const IQ& iq) { - const auto* ibb = iq.findExtension(ExtIBB); - if (ibb) { - IMContactId friendId(qstring(iq.from().bare())); - qDebug() << __func__ << QString("IBB stream id:%1").arg(qstring(ibb->sid())); - - switch (ibb->type()) { - case InBandBytestream::IBBOpen: { - qDebug() << __func__ << QString("Open"); - break; - } - // case InBandBytestream::IBBData: { - // qDebug() << __func__ << QString("Data seq:%1").arg(ibb->seq()); - // emit receiveFileChunk(friendId, qstring(ibb->sid()), ibb->seq(), - // ibb->data()); break; - // } - // case InBandBytestream::IBBClose: { - // qDebug() << __func__ << QString("Close"); - // emit receiveFileFinished(friendId, qstring(ibb->sid())); - // break; - // } - default: { - } - } - - IQ riq(IQ::IqType::Result, iq.from(), iq.id()); - _im->getClient()->send(riq); - } - return true; - // auto services = iq.tag()->findChild("services", "xmlns", - // XMLNS_EXTERNAL_SERVICE_DISCOVERY); if (services) { - // mExtDisco = ExtDisco(services); - // } } void IMJingle::handleIqID(const IQ& iq, int context) {} diff --git a/src/lib/messenger/IMJingle.h b/src/lib/messenger/IMJingle.h index b45aeb56..00db200b 100644 --- a/src/lib/messenger/IMJingle.h +++ b/src/lib/messenger/IMJingle.h @@ -107,9 +107,12 @@ class IMJingle : public QObject, IMJingleSession* cacheSessionInfo(Jingle::Session* session, lib::ortc::JingleCallType callType); - virtual void sessionOnAccept(const QString& sId, const IMPeerId& peerId) = 0; + virtual void sessionOnAccept(const QString& sId, + Jingle::Session* session, + const IMPeerId& peerId) = 0; virtual void sessionOnTerminate(const QString& sId, const IMPeerId& peerId) = 0; virtual void sessionOnInitiate(const QString& sId, + Jingle::Session* session, const Jingle::Session::Jingle* jingle, const IMPeerId& peerId) = 0; IM* _im; diff --git a/src/lib/messenger/IMJingleSession.h b/src/lib/messenger/IMJingleSession.h index aa183f19..7112c204 100644 --- a/src/lib/messenger/IMJingleSession.h +++ b/src/lib/messenger/IMJingleSession.h @@ -33,6 +33,7 @@ using namespace gloox::Jingle; class IMJingSession { public: + virtual void start() = 0; virtual void stop() = 0; };