From 2b338d77da37ec3f863c4d43167c84640d872323 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 25 May 2011 16:46:40 +0200 Subject: [PATCH 1/5] Messaging using libpurple backend works again --- backends/libpurple/main.cpp | 6 ++++-- docs/Doxyfile | 2 +- spectrum/src/sample.cfg | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/backends/libpurple/main.cpp b/backends/libpurple/main.cpp index 1808444a..9db75849 100644 --- a/backends/libpurple/main.cpp +++ b/backends/libpurple/main.cpp @@ -74,6 +74,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { purple_accounts_add(account); } + m_sessions[user] = account; purple_account_set_password(account, password.c_str()); purple_account_set_enabled(account, "spectrum", TRUE); @@ -88,6 +89,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { const char *protocol = CONFIG_STRING(config, "service.protocol").c_str(); PurpleAccount *account = purple_accounts_find(legacyName.c_str(), protocol); if (account) { + m_sessions[user] = NULL; purple_account_set_enabled(account, "spectrum", FALSE); // Remove conversations. @@ -109,8 +111,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message) { const char *protocol = CONFIG_STRING(config, "service.protocol").c_str(); - PurpleAccount *account = purple_accounts_find(user.c_str(), protocol); - std::cout << user << "\n"; + PurpleAccount *account = m_sessions[user]; if (account) { PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, legacyName.c_str(), account); if (!conv) { @@ -122,6 +123,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { } } + std::map m_sessions; std::map m_accounts; private: Config *config; diff --git a/docs/Doxyfile b/docs/Doxyfile index 45a29656..8b58ca9b 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1445,7 +1445,7 @@ DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = "/usr/bin" +DOT_PATH = "" # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the diff --git a/spectrum/src/sample.cfg b/spectrum/src/sample.cfg index c02142fa..b564a4dc 100644 --- a/spectrum/src/sample.cfg +++ b/spectrum/src/sample.cfg @@ -4,8 +4,8 @@ password = secret server = 127.0.0.1 port = 5222 server_mode = 1 -#backend=../../backends/libpurple/libpurple_backend -backend=../../backends/libircclient-qt/libircclient-qt_backend +backend=../../backends/libpurple/libpurple_backend +#backend=../../backends/libircclient-qt/libircclient-qt_backend protocol=prpl-jabber [database] From 98687145b02a0f210415f2621a87d38ee0c167aa Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Thu, 26 May 2011 08:53:05 +0200 Subject: [PATCH 2/5] first more or less working version of multiple-backend support --- include/transport/networkplugin.h | 4 +- include/transport/networkpluginserver.h | 14 ++-- include/transport/user.h | 2 + src/networkplugin.cpp | 24 ++++--- src/networkpluginserver.cpp | 95 ++++++++++++++++--------- 5 files changed, 92 insertions(+), 47 deletions(-) diff --git a/include/transport/networkplugin.h b/include/transport/networkplugin.h index 50722a40..291d5d37 100644 --- a/include/transport/networkplugin.h +++ b/include/transport/networkplugin.h @@ -74,6 +74,7 @@ class NetworkPlugin { void send(const std::string &data); void sendPong(); + void pingTimeout(); std::string m_data; std::string m_host; @@ -81,7 +82,8 @@ class NetworkPlugin { Swift::BoostNetworkFactories *m_factories; Swift::BoostIOServiceThread m_boostIOServiceThread; boost::shared_ptr m_conn; - Swift::Timer::ref m_reconnectTimer; + Swift::Timer::ref m_pingTimer; + bool m_pingReceived; }; diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 05f99c61..7f89d756 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -40,6 +40,12 @@ class NetworkConversation; class NetworkPluginServer { public: + struct Client { + bool pongReceived; + std::list users; + std::string data; + }; + NetworkPluginServer(Component *component, Config *config, UserManager *userManager); virtual ~NetworkPluginServer(); @@ -67,15 +73,13 @@ class NetworkPluginServer { void send(boost::shared_ptr &, const std::string &data); void pingTimeout(); - void sendPing(); + void sendPing(boost::shared_ptr c); + boost::shared_ptr getFreeClient(); - std::string m_command; - std::string m_data; UserManager *m_userManager; Config *m_config; boost::shared_ptr m_server; - boost::shared_ptr m_client; - bool m_pongReceived; + std::map, Client > m_clients; Swift::Timer::ref m_pingTimer; }; diff --git a/include/transport/user.h b/include/transport/user.h index 0f5f6c07..96c63930 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -96,6 +96,8 @@ class User { bool m_connected; bool m_readyForConnect; Swift::Timer::ref m_reconnectTimer; + boost::shared_ptr connection; + friend class NetworkPluginServer; }; } diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index 26f8c242..d6726f7a 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -41,13 +41,14 @@ NetworkPlugin::NetworkPlugin(Swift::EventLoop *loop, const std::string &host, in m_factories = new Swift::BoostNetworkFactories(loop); m_host = host; m_port = port; + m_pingReceived = false; m_conn = m_factories->getConnectionFactory()->createConnection(); m_conn->onDataRead.connect(boost::bind(&NetworkPlugin::handleDataRead, this, _1)); m_conn->onConnectFinished.connect(boost::bind(&NetworkPlugin::handleConnected, this, _1)); m_conn->onDisconnected.connect(boost::bind(&NetworkPlugin::handleDisconnected, this)); - m_reconnectTimer = m_factories->getTimerFactory()->createTimer(1000); - m_reconnectTimer->onTick.connect(boost::bind(&NetworkPlugin::connect, this)); + m_pingTimer = m_factories->getTimerFactory()->createTimer(30000); + m_pingTimer->onTick.connect(boost::bind(&NetworkPlugin::pingTimeout, this)); connect(); } @@ -156,26 +157,25 @@ void NetworkPlugin::handleRoomChanged(const std::string &user, const std::string void NetworkPlugin::handleConnected(bool error) { if (error) { - std::cout << "Connecting error\n"; -// m_reconnectTimer->start(); + std::cerr << "Connecting error\n"; + m_pingTimer->stop(); exit(1); } else { std::cout << "Connected\n"; - m_reconnectTimer->stop(); + m_pingTimer->start(); } } void NetworkPlugin::handleDisconnected() { - std::cout << "Disconnected\n"; -// m_reconnectTimer->start(); + std::cerr << "Disconnected\n"; + m_pingTimer->stop(); exit(1); } void NetworkPlugin::connect() { std::cout << "Trying to connect the server\n"; m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(m_host), m_port)); - m_reconnectTimer->stop(); } void NetworkPlugin::handleLoginPayload(const std::string &data) { @@ -288,6 +288,7 @@ void NetworkPlugin::send(const std::string &data) { } void NetworkPlugin::sendPong() { + m_pingReceived = true; std::string message; pbnetwork::WrapperMessage wrap; wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PONG); @@ -297,4 +298,11 @@ void NetworkPlugin::sendPong() { // std::cout << "SENDING PONG\n"; } +void NetworkPlugin::pingTimeout() { + if (m_pingReceived == false) { + exit(1); + } + m_pingReceived = false; +} + } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 8ece5f56..8a0aa800 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -106,7 +106,6 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U m_userManager = userManager; m_config = config; component->m_factory = new NetworkFactory(this); - m_pongReceived = false; m_userManager->onUserCreated.connect(boost::bind(&NetworkPluginServer::handleUserCreated, this, _1)); m_userManager->onUserDestroyed.connect(boost::bind(&NetworkPluginServer::handleUserDestroyed, this, _1)); @@ -127,24 +126,30 @@ NetworkPluginServer::~NetworkPluginServer() { } void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr c) { - if (m_client) { - c->disconnect(); - } - m_client = c; - m_pongReceived = false; - + Client client; + client.pongReceived = true; + + m_clients[c] = client; c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, c)); c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, c, _1)); - sendPing(); + sendPing(c); m_pingTimer->start(); } void NetworkPluginServer::handleSessionFinished(boost::shared_ptr c) { - if (c == m_client) { - m_client.reset(); + for (std::list::const_iterator it = m_clients[c].users.begin(); it != m_clients[c].users.end(); it++) { + (*it)->handleDisconnected("Internal Server Error, please reconnect."); + } + + m_clients.erase(c); + + // Execute new session only if there's no free one after this crash/disconnection + for (std::map, Client>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { + if ((*it).second.users.size() < 1) { + return; + } } - m_pingTimer->stop(); exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str()); } @@ -274,23 +279,23 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool void NetworkPluginServer::handleDataRead(boost::shared_ptr c, const Swift::ByteArray &data) { long expected_size = 0; - m_data += data.toString(); + m_clients[c].data += data.toString(); // std::cout << "received data; size = " << m_data.size() << "\n"; - while (m_data.size() != 0) { - if (m_data.size() >= 4) { - unsigned char * head = (unsigned char*) m_data.c_str(); + while (m_clients[c].data.size() != 0) { + if (m_clients[c].data.size() >= 4) { + unsigned char * head = (unsigned char*) m_clients[c].data.c_str(); expected_size = (((((*head << 8) | *(head + 1)) << 8) | *(head + 2)) << 8) | *(head + 3); //expected_size = m_data[0]; // std::cout << "expected_size=" << expected_size << "\n"; - if (m_data.size() - 4 < expected_size) + if (m_clients[c].data.size() - 4 < expected_size) return; } else { return; } - std::string msg = m_data.substr(4, expected_size); - m_data.erase(0, 4 + expected_size); + std::string msg = m_clients[c].data.substr(4, expected_size); + m_clients[c].data.erase(0, 4 + expected_size); pbnetwork::WrapperMessage wrapper; if (wrapper.ParseFromString(msg) == false) { @@ -315,7 +320,7 @@ void NetworkPluginServer::handleDataRead(boost::shared_ptr c, handleConvMessagePayload(wrapper.payload(), true); break; case pbnetwork::WrapperMessage_Type_TYPE_PONG: - m_pongReceived = true; + m_clients[c].pongReceived = true; break; case pbnetwork::WrapperMessage_Type_TYPE_PARTICIPANT_CHANGED: handleParticipantChangedPayload(wrapper.payload()); @@ -339,12 +344,14 @@ void NetworkPluginServer::send(boost::shared_ptr &c, const st void NetworkPluginServer::pingTimeout() { std::cout << "pingtimeout\n"; - if (m_pongReceived) { - sendPing(); - m_pingTimer->start(); - } - else { - exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str()); + for (std::map, Client>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { + if ((*it).second.pongReceived) { + sendPing((*it).first); + m_pingTimer->start(); + } + else { + exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str()); + } } } @@ -367,8 +374,10 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) { login.SerializeToString(&message); WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGIN); + user->connection = getFreeClient(); + m_clients[user->connection].users.push_back(user); - send(m_client, message); + send(user->connection, message); } void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) { @@ -385,7 +394,7 @@ void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, con WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM); - send(m_client, message); + send(user->connection, message); NetworkConversation *conv = new NetworkConversation(user->getConversationManager(), r, true); conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2)); @@ -406,7 +415,7 @@ void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) { WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LEAVE_ROOM); - send(m_client, message); + send(user->connection, message); NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(r); if (!conv) { @@ -428,7 +437,15 @@ void NetworkPluginServer::handleUserDestroyed(User *user) { WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGOUT); - send(m_client, message); + send(user->connection, message); + + m_clients[user->connection].users.remove(user); + if (m_clients[user->connection].users.size() == 0) { + std::cout << "DISCONNECTING\n"; + user->connection->disconnect(); + user->connection.reset(); + m_clients.erase(user->connection); + } } void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost::shared_ptr &msg) { @@ -442,19 +459,31 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE); - send(m_client, message); + send(conv->getConversationManager()->getUser()->connection, message); } -void NetworkPluginServer::sendPing() { +void NetworkPluginServer::sendPing(boost::shared_ptr c) { std::string message; pbnetwork::WrapperMessage wrap; wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PING); wrap.SerializeToString(&message); - send(m_client, message); - m_pongReceived = false; + send(c, message); + m_clients[c].pongReceived = false; std::cout << "SENDING PING\n"; } +boost::shared_ptr NetworkPluginServer::getFreeClient() { + for (std::map, Client>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { + if ((*it).second.users.size() < 1) { + if ((*it).second.users.size() + 1 == 1) { + exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str()); + } + return (*it).first; + } + } + return boost::shared_ptr(); +} + } From 65d40a3359205c7ed91c681ed891bc5117beb4a6 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Fri, 27 May 2011 13:15:21 +0200 Subject: [PATCH 3/5] Stop unused backends --- src/networkplugin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/networkplugin.cpp b/src/networkplugin.cpp index d6726f7a..947bfd2d 100644 --- a/src/networkplugin.cpp +++ b/src/networkplugin.cpp @@ -299,10 +299,12 @@ void NetworkPlugin::sendPong() { } void NetworkPlugin::pingTimeout() { + std::cout << "PINGTIMEOUT " << m_pingReceived << " " << this << "\n"; if (m_pingReceived == false) { exit(1); } m_pingReceived = false; + m_pingTimer->start(); } } From cd64ebc24fdd873ca5416354582b112656cb4950 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Fri, 27 May 2011 13:43:22 +0200 Subject: [PATCH 4/5] Allocate backend before user connects --- src/networkpluginserver.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 8a0aa800..dd7b8070 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -356,6 +356,9 @@ void NetworkPluginServer::pingTimeout() { } void NetworkPluginServer::handleUserCreated(User *user) { + user->connection = getFreeClient(); + m_clients[user->connection].users.push_back(user); + // UserInfo userInfo = user->getUserInfo(); user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user)); user->onRoomJoined.connect(boost::bind(&NetworkPluginServer::handleRoomJoined, this, user, _1, _2, _3)); @@ -374,8 +377,6 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) { login.SerializeToString(&message); WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGIN); - user->connection = getFreeClient(); - m_clients[user->connection].users.push_back(user); send(user->connection, message); } From 3dc02f0cb31d549cdbe9cb665722b7964da08fd4 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Fri, 27 May 2011 14:57:44 +0200 Subject: [PATCH 5/5] Disconnect XMPP user if backend crashes or is killed --- docs/Doxyfile | 2 +- include/transport/networkpluginserver.h | 11 +-- include/transport/user.h | 1 - src/networkpluginserver.cpp | 101 +++++++++++++----------- 4 files changed, 63 insertions(+), 52 deletions(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index 8b58ca9b..45a29656 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -1445,7 +1445,7 @@ DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = "" +DOT_PATH = "/usr/bin" # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the diff --git a/include/transport/networkpluginserver.h b/include/transport/networkpluginserver.h index 7f89d756..082bbc42 100644 --- a/include/transport/networkpluginserver.h +++ b/include/transport/networkpluginserver.h @@ -44,6 +44,7 @@ class NetworkPluginServer { bool pongReceived; std::list users; std::string data; + boost::shared_ptr connection; }; NetworkPluginServer(Component *component, Config *config, UserManager *userManager); @@ -54,8 +55,8 @@ class NetworkPluginServer { private: void handleNewClientConnection(boost::shared_ptr c); - void handleSessionFinished(boost::shared_ptr); - void handleDataRead(boost::shared_ptr, const Swift::ByteArray&); + void handleSessionFinished(Client *c); + void handleDataRead(Client *c, const Swift::ByteArray&); void handleConnectedPayload(const std::string &payload); void handleDisconnectedPayload(const std::string &payload); @@ -73,13 +74,13 @@ class NetworkPluginServer { void send(boost::shared_ptr &, const std::string &data); void pingTimeout(); - void sendPing(boost::shared_ptr c); - boost::shared_ptr getFreeClient(); + void sendPing(Client *c); + Client *getFreeClient(); UserManager *m_userManager; Config *m_config; boost::shared_ptr m_server; - std::map, Client > m_clients; + std::list m_clients; Swift::Timer::ref m_pingTimer; }; diff --git a/include/transport/user.h b/include/transport/user.h index 96c63930..86f7214c 100644 --- a/include/transport/user.h +++ b/include/transport/user.h @@ -97,7 +97,6 @@ class User { bool m_readyForConnect; Swift::Timer::ref m_reconnectTimer; boost::shared_ptr connection; - friend class NetworkPluginServer; }; } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index dd7b8070..0542d589 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -126,27 +126,30 @@ NetworkPluginServer::~NetworkPluginServer() { } void NetworkPluginServer::handleNewClientConnection(boost::shared_ptr c) { - Client client; - client.pongReceived = true; + Client *client = new Client; + client->pongReceived = true; + client->connection = c; - m_clients[c] = client; + m_clients.push_back(client); - c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, c)); - c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, c, _1)); - sendPing(c); + c->onDisconnected.connect(boost::bind(&NetworkPluginServer::handleSessionFinished, this, client)); + c->onDataRead.connect(boost::bind(&NetworkPluginServer::handleDataRead, this, client, _1)); + sendPing(client); m_pingTimer->start(); } -void NetworkPluginServer::handleSessionFinished(boost::shared_ptr c) { - for (std::list::const_iterator it = m_clients[c].users.begin(); it != m_clients[c].users.end(); it++) { +void NetworkPluginServer::handleSessionFinished(Client *c) { + for (std::list::const_iterator it = c->users.begin(); it != c->users.end(); it++) { + (*it)->setData(NULL); (*it)->handleDisconnected("Internal Server Error, please reconnect."); } - m_clients.erase(c); + m_clients.remove(c); + delete c; // Execute new session only if there's no free one after this crash/disconnection - for (std::map, Client>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { - if ((*it).second.users.size() < 1) { + for (std::list::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { + if ((*it)->users.size() < 1) { return; } } @@ -277,25 +280,25 @@ void NetworkPluginServer::handleConvMessagePayload(const std::string &data, bool conv->handleMessage(msg, payload.nickname()); } -void NetworkPluginServer::handleDataRead(boost::shared_ptr c, const Swift::ByteArray &data) { +void NetworkPluginServer::handleDataRead(Client *c, const Swift::ByteArray &data) { long expected_size = 0; - m_clients[c].data += data.toString(); + c->data += data.toString(); // std::cout << "received data; size = " << m_data.size() << "\n"; - while (m_clients[c].data.size() != 0) { - if (m_clients[c].data.size() >= 4) { - unsigned char * head = (unsigned char*) m_clients[c].data.c_str(); + while (c->data.size() != 0) { + if (c->data.size() >= 4) { + unsigned char * head = (unsigned char*) c->data.c_str(); expected_size = (((((*head << 8) | *(head + 1)) << 8) | *(head + 2)) << 8) | *(head + 3); //expected_size = m_data[0]; // std::cout << "expected_size=" << expected_size << "\n"; - if (m_clients[c].data.size() - 4 < expected_size) + if (c->data.size() - 4 < expected_size) return; } else { return; } - std::string msg = m_clients[c].data.substr(4, expected_size); - m_clients[c].data.erase(0, 4 + expected_size); + std::string msg = c->data.substr(4, expected_size); + c->data.erase(0, 4 + expected_size); pbnetwork::WrapperMessage wrapper; if (wrapper.ParseFromString(msg) == false) { @@ -320,7 +323,7 @@ void NetworkPluginServer::handleDataRead(boost::shared_ptr c, handleConvMessagePayload(wrapper.payload(), true); break; case pbnetwork::WrapperMessage_Type_TYPE_PONG: - m_clients[c].pongReceived = true; + c->pongReceived = true; break; case pbnetwork::WrapperMessage_Type_TYPE_PARTICIPANT_CHANGED: handleParticipantChangedPayload(wrapper.payload()); @@ -344,9 +347,9 @@ void NetworkPluginServer::send(boost::shared_ptr &c, const st void NetworkPluginServer::pingTimeout() { std::cout << "pingtimeout\n"; - for (std::map, Client>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { - if ((*it).second.pongReceived) { - sendPing((*it).first); + for (std::list::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { + if ((*it)->pongReceived) { + sendPing((*it)); m_pingTimer->start(); } else { @@ -356,8 +359,9 @@ void NetworkPluginServer::pingTimeout() { } void NetworkPluginServer::handleUserCreated(User *user) { - user->connection = getFreeClient(); - m_clients[user->connection].users.push_back(user); + Client *c = getFreeClient(); + user->setData(c); + c->users.push_back(user); // UserInfo userInfo = user->getUserInfo(); user->onReadyToConnect.connect(boost::bind(&NetworkPluginServer::handleUserReadyToConnect, this, user)); @@ -378,7 +382,8 @@ void NetworkPluginServer::handleUserReadyToConnect(User *user) { WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGIN); - send(user->connection, message); + Client *c = (Client *) user->getData(); + send(c->connection, message); } void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, const std::string &nickname, const std::string &password) { @@ -395,7 +400,8 @@ void NetworkPluginServer::handleRoomJoined(User *user, const std::string &r, con WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_JOIN_ROOM); - send(user->connection, message); + Client *c = (Client *) user->getData(); + send(c->connection, message); NetworkConversation *conv = new NetworkConversation(user->getConversationManager(), r, true); conv->onMessageToSend.connect(boost::bind(&NetworkPluginServer::handleMessageReceived, this, _1, _2)); @@ -416,7 +422,8 @@ void NetworkPluginServer::handleRoomLeft(User *user, const std::string &r) { WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LEAVE_ROOM); - send(user->connection, message); + Client *c = (Client *) user->getData(); + send(c->connection, message); NetworkConversation *conv = (NetworkConversation *) user->getConversationManager()->getConversation(r); if (!conv) { @@ -438,14 +445,17 @@ void NetworkPluginServer::handleUserDestroyed(User *user) { WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_LOGOUT); - send(user->connection, message); - - m_clients[user->connection].users.remove(user); - if (m_clients[user->connection].users.size() == 0) { + Client *c = (Client *) user->getData(); + if (!c) { + return; + } + send(c->connection, message); + c->users.remove(user); + if (c->users.size() == 0) { std::cout << "DISCONNECTING\n"; - user->connection->disconnect(); - user->connection.reset(); - m_clients.erase(user->connection); + c->connection->disconnect(); + c->connection.reset(); +// m_clients.erase(user->connection); } } @@ -460,31 +470,32 @@ void NetworkPluginServer::handleMessageReceived(NetworkConversation *conv, boost WRAP(message, pbnetwork::WrapperMessage_Type_TYPE_CONV_MESSAGE); - send(conv->getConversationManager()->getUser()->connection, message); + Client *c = (Client *) conv->getConversationManager()->getUser()->getData(); + send(c->connection, message); } -void NetworkPluginServer::sendPing(boost::shared_ptr c) { +void NetworkPluginServer::sendPing(Client *c) { std::string message; pbnetwork::WrapperMessage wrap; wrap.set_type(pbnetwork::WrapperMessage_Type_TYPE_PING); wrap.SerializeToString(&message); - send(c, message); - m_clients[c].pongReceived = false; + send(c->connection, message); + c->pongReceived = false; std::cout << "SENDING PING\n"; } -boost::shared_ptr NetworkPluginServer::getFreeClient() { - for (std::map, Client>::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { - if ((*it).second.users.size() < 1) { - if ((*it).second.users.size() + 1 == 1) { +NetworkPluginServer::Client *NetworkPluginServer::getFreeClient() { + for (std::list::const_iterator it = m_clients.begin(); it != m_clients.end(); it++) { + if ((*it)->users.size() < 1) { + if ((*it)->users.size() + 1 == 1) { exec_(CONFIG_STRING(m_config, "service.backend").c_str(), "localhost", "10000", m_config->getConfigFile().c_str()); } - return (*it).first; + return (*it); } } - return boost::shared_ptr(); + return NULL; } }