From 353588c406a6cdfd8b0966236e4a6c53526af7fe Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 24 Oct 2012 10:53:26 +0200 Subject: [PATCH] Try to join the rooms after every reconnect, not only after first one --- include/transport/conversationmanager.h | 2 ++ include/transport/user.h | 4 +-- src/conversationmanager.cpp | 9 +++++ src/tests/user.cpp | 22 +++++++++--- src/user.cpp | 45 ++++++++++++++++++------- 5 files changed, 63 insertions(+), 19 deletions(-) diff --git a/include/transport/conversationmanager.h b/include/transport/conversationmanager.h index 016914c8..865736b2 100644 --- a/include/transport/conversationmanager.h +++ b/include/transport/conversationmanager.h @@ -69,6 +69,8 @@ class ConversationManager { /// \param conv Conversation. void removeConversation(Conversation *conv); + void deleteAllConversations(); + void resetResources(); void removeJID(const Swift::JID &jid); diff --git a/include/transport/user.h b/include/transport/user.h index 47a1206c..1719b13d 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -78,7 +78,7 @@ class User : public Swift::EntityCapsProvider { /// Handles presence from XMPP JID associated with this user. /// \param presence Swift::Presence. - void handlePresence(Swift::Presence::ref presence); + void handlePresence(Swift::Presence::ref presence, bool forceJoin = false); void handleSubscription(Swift::Presence::ref presence); @@ -144,7 +144,7 @@ class User : public Swift::EntityCapsProvider { std::vector > m_filetransfers; int m_resources; int m_reconnectCounter; - std::vector m_joinedRooms; + std::list m_joinedRooms; }; } diff --git a/src/conversationmanager.cpp b/src/conversationmanager.cpp index 4fc23afc..066a4603 100644 --- a/src/conversationmanager.cpp +++ b/src/conversationmanager.cpp @@ -47,6 +47,15 @@ ConversationManager::~ConversationManager() { } } +void ConversationManager::deleteAllConversations() { + while(!m_convs.empty()) { + LOG4CXX_INFO(logger, m_user->getJID().toString() << ": Removing conversation " << (*m_convs.begin()).first); + (*m_convs.begin()).second->destroyRoom(); + delete (*m_convs.begin()).second; + m_convs.erase(m_convs.begin()); + } +} + Conversation *ConversationManager::getConversation(const std::string &name) { if (m_convs.find(name) != m_convs.end()) return m_convs[name]; diff --git a/src/tests/user.cpp b/src/tests/user.cpp index 84914b6e..054cc100 100644 --- a/src/tests/user.cpp +++ b/src/tests/user.cpp @@ -33,6 +33,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_TEST(joinRoomBeforeConnected); CPPUNIT_TEST(handleDisconnected); CPPUNIT_TEST(handleDisconnectedReconnect); + CPPUNIT_TEST(joinRoomHandleDisconnectedRejoin); CPPUNIT_TEST_SUITE_END(); public: @@ -319,6 +320,12 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { user = userManager->getUser("user@localhost"); CPPUNIT_ASSERT(user); CPPUNIT_ASSERT(readyToConnect); + + Swift::Presence::ref response = Swift::Presence::create(); + response->setTo("localhost"); + response->setFrom("user@localhost/resource"); + injectPresence(response); + loop->processEvents(); } void joinRoomBeforeConnected() { @@ -347,15 +354,22 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest { CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); + } + void joinRoomHandleDisconnectedRejoin() { + User *user = userManager->getUser("user@localhost"); + handlePresenceJoinRoom(); + handleDisconnectedReconnect(); room = ""; roomNickname = ""; roomPassword = ""; - + received.clear(); user->setConnected(true); - CPPUNIT_ASSERT_EQUAL(std::string(""), room); - CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname); - CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword); + + CPPUNIT_ASSERT_EQUAL(std::string("#room"), room); + CPPUNIT_ASSERT_EQUAL(std::string("hanzz"), roomNickname); + CPPUNIT_ASSERT_EQUAL(std::string("password"), roomPassword); + CPPUNIT_ASSERT_EQUAL(0, (int) received.size()); } }; diff --git a/src/user.cpp b/src/user.cpp index cf0b2f1c..558138a2 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -179,18 +179,18 @@ void User::setConnected(bool connected) { if (m_connected) { BOOST_FOREACH(Swift::Presence::ref &presence, m_joinedRooms) { - handlePresence(presence); + handlePresence(presence, true); } - m_joinedRooms.clear(); } } -void User::handlePresence(Swift::Presence::ref presence) { +void User::handlePresence(Swift::Presence::ref presence, bool forceJoin) { int currentResourcesCount = m_presenceOracle->getAllPresence(m_jid).size(); m_conversationManager->resetResources(); + LOG4CXX_INFO(logger, "PRESENCE " << presence->getFrom().toString() << " " << presence->getTo().toString()); if (!m_connected) { // we are not connected to legacy network, so we should do it when disco#info arrive :) if (m_readyForConnect == false) { @@ -236,6 +236,13 @@ void User::handlePresence(Swift::Presence::ref presence) { LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room); onRoomLeft(room); + BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) { + if (p->getTo() == presence->getTo()) { + m_joinedRooms.remove(p); + break; + } + } + if (conv) { m_conversationManager->removeConversation(conv); delete conv; @@ -250,14 +257,11 @@ void User::handlePresence(Swift::Presence::ref presence) { } std::string room = Buddy::JIDToLegacyName(presence->getTo()); - - if (!m_connected) { - LOG4CXX_INFO(logger, m_jid.toString() << ": Joining room " << room << " postponed, because use is not connected to legacy network yet."); - m_joinedRooms.push_back(presence); - return; + std::string password = ""; + if (presence->getPayload() != NULL) { + password = presence->getPayload()->getPassword() ? *presence->getPayload()->getPassword() : ""; } - Conversation *conv = m_conversationManager->getConversation(room); if (conv != NULL) { if (std::find(conv->getJIDs().begin(), conv->getJIDs().end(), presence->getFrom()) != conv->getJIDs().end()) { @@ -267,14 +271,29 @@ void User::handlePresence(Swift::Presence::ref presence) { conv->addJID(presence->getFrom()); conv->sendParticipants(presence->getFrom()); } + + if (forceJoin) { + onRoomJoined(presence->getFrom(), room, presence->getTo().getResource(), password); + } + return; + } + + bool isInJoined = false; + BOOST_FOREACH(Swift::Presence::ref &p, m_joinedRooms) { + if (p->getTo() == presence->getTo()) { + isInJoined = true; + } + } + if (!isInJoined) { + m_joinedRooms.push_back(presence); + } + + if (!m_connected) { + LOG4CXX_INFO(logger, m_jid.toString() << ": Joining room " << room << " postponed, because use is not connected to legacy network yet."); return; } LOG4CXX_INFO(logger, m_jid.toString() << ": Going to join room " << room << " as " << presence->getTo().getResource()); - std::string password = ""; - if (presence->getPayload() != NULL) { - password = presence->getPayload()->getPassword() ? *presence->getPayload()->getPassword() : ""; - } conv = m_component->getFactory()->createConversation(m_conversationManager, room, true); m_conversationManager->addConversation(conv);