qxmpp-project / qxmpp

Cross-platform C++ XMPP client and server library
408 stars 197 forks source link

XmppIq issue with xmpp response #505

Closed ronhanic closed 1 year ago

ronhanic commented 1 year ago

I am using XmppClient to connect to Cisco Finesse services. I am really a newby so... I don't know what i am doing First the items below register to a team subscription. Team A i then subscribe to it and it should respond telling me that I am subscribed

I run wireshark and i see the iq message response. and the important thing is that it actually works. however i went to try to figure out how to check the subscription attribute (subscription="subscribed") in the iq type=result response and i cannot figure out how to do it. the Future never returns. The xmpp stanzas for most of the other xmpp responses are actually coming out in an separate piece of code that overrides handleStanza(). but i never see this iq in that handler.

the connect never prints out the debug coe finished() #1.

question1: should the stanzas for this be printed somewhere. I believe they should be in my class that overrides the handleStanza

i have a class that does this and i do see Pings and other xmpp messages. just not this type.

XmppSubManager::XmppSubManager() : QXmppClientExtension() {

}

bool XmppSubManager::handleStanza(const QDomElement &element) { should i see the iq message here? it isn't so i must be doing something wrong. }

QUestion 2 should i be seeing auto result = watcher.future().result(); at some point. The connect call never ever returns the future.

Thanks to Anyone who responds. !!

connect(&watcher, &QFutureWatcher::finished, [&watcher]{

    qDebug() << "xmpp xmppSubscribe_team() finished()#1";

QXmppPubSubIq iq; iq.setId("subscribe_team"); iq.setTo(m_systemInfo->xmppPubSubDomain()); iq.setFrom(QString("%0@%1").arg(m_userId, m_systemInfo->xmppDomain())); iq.setType(QXmppIq::Set); iq.setQueryType(QXmppPubSubIq::SubscribeQuery); iq.setQueryJid(QString("%0@%1/%2").arg(m_userId, m_systemInfo->xmppDomain(), m_xmppResource)); iq.setQueryNode(QString("/finesse/api/Team/%1/Users").arg(m_monitoringTeamId));

QFutureWatcher<QXmppClient::IqResult> watcher;

QFuture<QXmppClient::IqResult> future =  m_xmppClient->sendIq(iq);       

watcher.setFuture(future);

QThread::currentThread()->setObjectName("main");

connect(&watcher, &QFutureWatcher<QXmppClient::IqResult>::finished, [&watcher]{

    qDebug() << "xmpp xmppSubscribe_team() finished()#1";

    auto result = watcher.future().result();

    qCInfo(FinesseApp) << "xmpp xmppSubscribe_team() finished()";

});
lnjX commented 1 year ago

You stack-allocated the QFutureWatcher, so it is deleted at the end of the scope and the signal connection is destroyed.

You can use the await() helper function on Qt 5 or QFuture::then() on Qt 6. That's easier.

https://github.com/qxmpp-project/qxmpp/blob/befab2fe2e71330170bba48f173258be724c65b9/src/base/QXmppFutureUtils_p.h#L101-L123


Stanzas sent via QXmppClient::sendIq() can only be received via the returned future, not QXmppClientExtension::handleStanza().

You may also want to use the new QXmppPubSubManager: https://doc.qxmpp.org/qxmpp-dev/classQXmppPubSubManager.html

ronhanic commented 1 year ago

thanks so much for the reply

I created an await function (i could not figure out how to create the handler template) I do now get it returning and looking in the result.index i get 0 and 1. but the result should have XMl and i am wondering how to get the xml out. Thanks so much for replying.

void await(const QFuture &future, QObject context) { qDebug() << "out.ttxt future"; auto watcher = new QFutureWatcher(context); QObject::connect(watcher,&QFutureWatcherBase::finished, context,[watcher]() { // qDebug() << "index=" << watcher->result().index();

                            auto result = watcher->future().result();

                            qDebug() << "index  xmppSubscribe_team() finished()" ;

                            if(auto pval = std::get_if<QDomElement>(&result)) {
                                QString str;
                                QTextStream in(&str);
                                qDebug() << "index str=" << str ;
                            }

                            watcher->deleteLater();
                    });

     watcher->setFuture(future);

}