Do not disconnect from room when user uses two clients and shutdown one.
This commit is contained in:
parent
2f542b5077
commit
88607aff3c
6 changed files with 104 additions and 11 deletions
|
@ -82,6 +82,18 @@ class Conversation {
|
|||
m_jid = jid;
|
||||
}
|
||||
|
||||
void addJID(const Swift::JID &jid) {
|
||||
m_jids.push_back(jid);
|
||||
}
|
||||
|
||||
void removeJID(const Swift::JID &jid) {
|
||||
m_jids.remove(jid);
|
||||
}
|
||||
|
||||
const std::list<Swift::JID> &getJIDs() {
|
||||
return m_jids;
|
||||
}
|
||||
|
||||
/// Sends message to Legacy network.
|
||||
|
||||
/// \param message Message.
|
||||
|
@ -123,6 +135,7 @@ class Conversation {
|
|||
std::string m_room;
|
||||
bool m_muc;
|
||||
Swift::JID m_jid;
|
||||
std::list<Swift::JID> m_jids;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -115,9 +115,11 @@ void Conversation::handleMessage(boost::shared_ptr<Swift::Message> &message, con
|
|||
if (n.empty()) {
|
||||
n = " ";
|
||||
}
|
||||
message->setTo(m_jid);
|
||||
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
|
||||
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
|
||||
message->setTo(jid);
|
||||
message->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), n));
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,7 +133,6 @@ void Conversation::handleParticipantChanged(const std::string &nick, int flag, i
|
|||
}
|
||||
}
|
||||
presence->setFrom(Swift::JID(legacyName, m_conversationManager->getComponent()->getJID().toBare(), nickname));
|
||||
presence->setTo(m_jid);
|
||||
presence->setType(Swift::Presence::Available);
|
||||
|
||||
if (!statusMessage.empty())
|
||||
|
@ -174,7 +175,10 @@ void Conversation::handleParticipantChanged(const std::string &nick, int flag, i
|
|||
p->addItem(item);
|
||||
|
||||
presence->addPayload(boost::shared_ptr<Swift::Payload>(p));
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
BOOST_FOREACH(const Swift::JID &jid, m_jids) {
|
||||
presence->setTo(jid);
|
||||
m_conversationManager->getComponent()->getStanzaChannel()->sendPresence(presence);
|
||||
}
|
||||
if (!newname.empty()) {
|
||||
handleParticipantChanged(newname, flag, status, statusMessage);
|
||||
}
|
||||
|
|
|
@ -1192,7 +1192,7 @@ void NetworkPluginServer::handleRoomJoined(User *user, const Swift::JID &who, co
|
|||
user->getConversationManager()->addConversation(conv);
|
||||
conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2));
|
||||
conv->setNickname(nickname);
|
||||
conv->setJID(who);
|
||||
conv->addJID(who);
|
||||
}
|
||||
|
||||
void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) {
|
||||
|
|
|
@ -158,7 +158,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
user->getConversationManager()->addConversation(conv);
|
||||
conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
|
||||
conv->setNickname("nickname");
|
||||
conv->setJID("user@localhost/resource");
|
||||
conv->addJID("user@localhost/resource");
|
||||
|
||||
// reset resources should not touch this resource
|
||||
user->getConversationManager()->resetResources();
|
||||
|
@ -197,7 +197,7 @@ class ConversationManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTe
|
|||
|
||||
conv->onMessageToSend.connect(boost::bind(&ConversationManagerTest::handleMessageReceived, this, _1, _2));
|
||||
conv->setNickname("nickname");
|
||||
conv->setJID("user@localhost/resource");
|
||||
conv->addJID("user@localhost/resource");
|
||||
|
||||
// normal presence
|
||||
conv->handleParticipantChanged("anotheruser", 0, Swift::StatusShow::Away, "my status message");
|
||||
|
|
|
@ -25,7 +25,9 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_TEST(sendCurrentPresence);
|
||||
CPPUNIT_TEST(handlePresence);
|
||||
CPPUNIT_TEST(handlePresenceJoinRoom);
|
||||
CPPUNIT_TEST(handlePresenceJoinRoomTwoResources);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoom);
|
||||
CPPUNIT_TEST(handlePresenceLeaveRoomTwoResources);
|
||||
CPPUNIT_TEST(leaveJoinedRoom);
|
||||
CPPUNIT_TEST(handleDisconnected);
|
||||
CPPUNIT_TEST(handleDisconnectedReconnect);
|
||||
|
@ -139,6 +141,7 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
|
||||
// simulate that backend joined the room
|
||||
TestingConversation *conv = new TestingConversation(user->getConversationManager(), "#room", true);
|
||||
conv->addJID("user@localhost/resource");
|
||||
user->getConversationManager()->addConversation(conv);
|
||||
|
||||
received.clear();
|
||||
|
@ -154,6 +157,24 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
}
|
||||
|
||||
void handlePresenceJoinRoomTwoResources() {
|
||||
handlePresenceJoinRoom();
|
||||
connectSecondResource();
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource2");
|
||||
|
||||
Swift::MUCPayload *payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), room);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
}
|
||||
|
||||
void handlePresenceLeaveRoom() {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
|
@ -173,6 +194,48 @@ class UserTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
|||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
}
|
||||
|
||||
void handlePresenceLeaveRoomTwoResources() {
|
||||
handlePresenceJoinRoomTwoResources();
|
||||
received.clear();
|
||||
|
||||
// User is still connected from resource2, so he should not leave the room
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource");
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
|
||||
Swift::MUCPayload *payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), room);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
|
||||
// disconnect also from resource
|
||||
// User is still connected from resource2, so he should not leave the room
|
||||
response = Swift::Presence::create();
|
||||
response->setTo("#room@localhost/hanzz");
|
||||
response->setFrom("user@localhost/resource2");
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
|
||||
payload = new Swift::MUCPayload();
|
||||
payload->setPassword("password");
|
||||
response->addPayload(boost::shared_ptr<Swift::Payload>(payload));
|
||||
injectPresence(response);
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(0, (int) received.size());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("#room"), room);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomNickname);
|
||||
CPPUNIT_ASSERT_EQUAL(std::string(""), roomPassword);
|
||||
}
|
||||
|
||||
void leaveJoinedRoom() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
handlePresenceJoinRoom();
|
||||
|
|
19
src/user.cpp
19
src/user.cpp
|
@ -218,10 +218,17 @@ void User::handlePresence(Swift::Presence::ref presence) {
|
|||
if (isMUC) {
|
||||
if (presence->getType() == Swift::Presence::Unavailable) {
|
||||
std::string room = Buddy::JIDToLegacyName(presence->getTo());
|
||||
Conversation *conv = m_conversationManager->getConversation(room);
|
||||
if (conv) {
|
||||
conv->removeJID(presence->getFrom());
|
||||
if (!conv->getJIDs().empty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": Going to left room " << room);
|
||||
onRoomLeft(room);
|
||||
|
||||
Conversation *conv = m_conversationManager->getConversation(room);
|
||||
if (conv) {
|
||||
m_conversationManager->removeConversation(conv);
|
||||
delete conv;
|
||||
|
@ -235,8 +242,14 @@ void User::handlePresence(Swift::Presence::ref presence) {
|
|||
onReadyToConnect();
|
||||
}
|
||||
std::string room = Buddy::JIDToLegacyName(presence->getTo());
|
||||
if (m_conversationManager->getConversation(room) != NULL) {
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": User has already tried to join room " << room << " as " << presence->getTo().getResource());
|
||||
Conversation *conv = m_conversationManager->getConversation(room);
|
||||
if (conv != NULL) {
|
||||
if (std::find(conv->getJIDs().begin(), conv->getJIDs().end(), presence->getFrom()) != conv->getJIDs().end()) {
|
||||
LOG4CXX_INFO(logger, m_jid.toString() << ": User has already tried to join room " << room << " as " << presence->getTo().getResource());
|
||||
}
|
||||
else {
|
||||
conv->addJID(presence->getFrom());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue