Hopefully working disconnecting/connecting when more resources are connected
This commit is contained in:
parent
93ddc62068
commit
c7f2b62980
13 changed files with 179 additions and 74 deletions
|
@ -134,12 +134,12 @@ void Server::handleSessionStarted(boost::shared_ptr<ServerFromClientSession> ses
|
|||
}
|
||||
|
||||
void Server::handleSessionFinished(boost::shared_ptr<ServerFromClientSession> session) {
|
||||
if (!session->getRemoteJID().isValid()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getBareJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
dynamic_cast<ServerStanzaChannel *>(stanzaChannel_)->onPresenceReceived(presence);
|
||||
}
|
||||
// if (!session->getRemoteJID().isValid()) {
|
||||
// Swift::Presence::ref presence = Swift::Presence::create();
|
||||
// presence->setFrom(session->getBareJID());
|
||||
// presence->setType(Swift::Presence::Unavailable);
|
||||
// dynamic_cast<ServerStanzaChannel *>(stanzaChannel_)->onPresenceReceived(presence);
|
||||
// }
|
||||
serverFromClientSessions.erase(std::remove(serverFromClientSessions.begin(), serverFromClientSessions.end(), session), serverFromClientSessions.end());
|
||||
std::cout << "FINISH SESSION2 " << serverFromClientSessions.size() << "\n";
|
||||
session->onSessionStarted.disconnect(
|
||||
|
|
|
@ -45,32 +45,21 @@ ServerFromClientSession::ServerFromClientSession(
|
|||
}
|
||||
|
||||
ServerFromClientSession::~ServerFromClientSession() {
|
||||
std::cout << "DESTRUCTOR;\n";
|
||||
userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
|
||||
userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
|
||||
if (tlsLayer) {
|
||||
delete tlsLayer;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handlePasswordValid(const std::string &user) {
|
||||
if (user != JID(user_, getLocalJID().getDomain()).toString())
|
||||
return;
|
||||
void ServerFromClientSession::handlePasswordValid() {
|
||||
if (!isInitialized()) {
|
||||
userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
|
||||
userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
|
||||
authenticated_ = true;
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handlePasswordInvalid(const std::string &user) {
|
||||
if (user != JID(user_, getLocalJID().getDomain()).toString() || authenticated_)
|
||||
return;
|
||||
void ServerFromClientSession::handlePasswordInvalid() {
|
||||
if (!isInitialized()) {
|
||||
userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
|
||||
userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
|
||||
finishSession(AuthenticationFailedError);
|
||||
}
|
||||
|
@ -91,18 +80,7 @@ void ServerFromClientSession::handleElement(boost::shared_ptr<Element> element)
|
|||
else {
|
||||
PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
|
||||
user_ = plainMessage.getAuthenticationID();
|
||||
userRegistry_->onPasswordInvalid(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()).toBare().toString());
|
||||
userRegistry_->onPasswordValid.connect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1));
|
||||
userRegistry_->onPasswordInvalid.connect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1));
|
||||
if (userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), plainMessage.getPassword())) {
|
||||
// we're waiting for usermanager signal now
|
||||
// authenticated_ = true;
|
||||
// getXMPPLayer()->resetParser();
|
||||
}
|
||||
else {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
|
||||
finishSession(AuthenticationFailedError);
|
||||
}
|
||||
userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), this, plainMessage.getPassword());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -170,6 +148,10 @@ void ServerFromClientSession::setAllowSASLEXTERNAL() {
|
|||
allowSASLEXTERNAL = true;
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleSessionFinished(const boost::optional<SessionError>&) {
|
||||
userRegistry_->stopLogin(JID(user_, getLocalJID().getDomain()), this);
|
||||
}
|
||||
|
||||
void ServerFromClientSession::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, const PKCS12Certificate& cert) {
|
||||
tlsLayer = new TLSServerLayer(tlsContextFactory);
|
||||
if (!tlsLayer->setServerCertificate(cert)) {
|
||||
|
|
|
@ -53,11 +53,13 @@ namespace Swift {
|
|||
return Swift::JID(user_, getLocalJID().getDomain());
|
||||
}
|
||||
|
||||
void handlePasswordValid();
|
||||
void handlePasswordInvalid();
|
||||
|
||||
private:
|
||||
void handleElement(boost::shared_ptr<Element>);
|
||||
void handleStreamStart(const ProtocolHeader& header);
|
||||
void handlePasswordValid(const std::string &user);
|
||||
void handlePasswordInvalid(const std::string &user);
|
||||
void handleSessionFinished(const boost::optional<SessionError>&);
|
||||
|
||||
void setInitialized();
|
||||
bool isInitialized() const {
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace {
|
|||
}
|
||||
|
||||
void ServerStanzaChannel::addSession(boost::shared_ptr<ServerFromClientSession> session) {
|
||||
std::cout << "ADDING SESSION\n";
|
||||
sessions[session->getRemoteJID().toBare().toString()].push_back(session);
|
||||
session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
|
||||
session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
|
||||
|
@ -53,20 +54,30 @@ void ServerStanzaChannel::sendPresence(boost::shared_ptr<Presence> presence) {
|
|||
send(presence);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element) {
|
||||
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element, bool last) {
|
||||
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
|
||||
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
|
||||
if (element) {
|
||||
(*i)->sendElement(element);
|
||||
}
|
||||
candidateSessions.push_back(*i);
|
||||
}
|
||||
|
||||
for (std::vector<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
|
||||
|
||||
removeSession(*i);
|
||||
if (element) {
|
||||
(*i)->sendElement(element);
|
||||
}
|
||||
|
||||
if (last && (*i)->getRemoteJID().isValid()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom((*i)->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
}
|
||||
|
||||
(*i)->finishSession();
|
||||
sessions[to.toBare().toString()].remove(*i);
|
||||
std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,10 +120,12 @@ void ServerStanzaChannel::send(boost::shared_ptr<Stanza> stanza) {
|
|||
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession>& session) {
|
||||
removeSession(session);
|
||||
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
// if (!session->initiatedFinish()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
// }
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession>& session) {
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace Swift {
|
|||
void sendMessage(boost::shared_ptr<Message> message);
|
||||
void sendPresence(boost::shared_ptr<Presence> presence);
|
||||
|
||||
void finishSession(const JID& to, boost::shared_ptr<Element> element);
|
||||
void finishSession(const JID& to, boost::shared_ptr<Element> element, bool last = false);
|
||||
|
||||
bool getStreamManagementEnabled() const {
|
||||
return false;
|
||||
|
|
|
@ -11,9 +11,16 @@ namespace Swift {
|
|||
SimpleUserRegistry::SimpleUserRegistry() {
|
||||
}
|
||||
|
||||
bool SimpleUserRegistry::isValidUserPassword(const JID& user, const SafeByteArray& password) {
|
||||
void SimpleUserRegistry::isValidUserPassword(const JID& user, ServerFromClientSession *session, const SafeByteArray& password) {
|
||||
std::map<JID,SafeByteArray>::const_iterator i = users.find(user);
|
||||
return i != users.end() ? i->second == password : false;
|
||||
|
||||
|
||||
if (i != users.end() && i->second == password) {
|
||||
session->handlePasswordValid();
|
||||
}
|
||||
else {
|
||||
session->handlePasswordInvalid();
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleUserRegistry::addUser(const JID& user, const std::string& password) {
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace Swift {
|
|||
public:
|
||||
SimpleUserRegistry();
|
||||
|
||||
virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password);
|
||||
virtual void isValidUserPassword(const JID& user, ServerFromClientSession *session, const SafeByteArray& password);
|
||||
void addUser(const JID& user, const std::string& password);
|
||||
|
||||
private:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <string>
|
||||
#include <Swiften/Base/SafeByteArray.h>
|
||||
#include <boost/signal.hpp>
|
||||
#include "Swiften/Server/ServerFromClientSession.h"
|
||||
|
||||
namespace Swift {
|
||||
class JID;
|
||||
|
@ -17,12 +18,8 @@ namespace Swift {
|
|||
public:
|
||||
virtual ~UserRegistry();
|
||||
|
||||
virtual bool isValidUserPassword(const JID& user, const SafeByteArray& password) = 0;
|
||||
|
||||
virtual void stopLogin(const JID &/*user*/) {};
|
||||
|
||||
boost::signal<void (const std::string &user)> onPasswordValid;
|
||||
boost::signal<void (const std::string &user)> onPasswordInvalid;
|
||||
virtual void isValidUserPassword(const JID& user, ServerFromClientSession *session, const SafeByteArray& password) = 0;
|
||||
|
||||
virtual void stopLogin(const JID &/*user*/, ServerFromClientSession *) {};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -180,7 +180,7 @@ namespace Transport {
|
|||
Swift::PresenceOracle *m_presenceOracle;
|
||||
Swift::StanzaChannel *m_stanzaChannel;
|
||||
Swift::IQRouter *m_iqRouter;
|
||||
Swift::UserRegistry *m_userRegistry;
|
||||
Transport::UserRegistry *m_userRegistry;
|
||||
StorageBackend *m_storageBackend;
|
||||
DiscoInfoResponder *m_discoInfoResponder;
|
||||
DiscoItemsResponder *m_discoItemsResponder;
|
||||
|
|
|
@ -82,6 +82,7 @@ class UserManager {
|
|||
}
|
||||
|
||||
void connectUser(const Swift::JID &user);
|
||||
void disconnectUser(const Swift::JID &user);
|
||||
|
||||
private:
|
||||
void handlePresence(Swift::Presence::ref presence);
|
||||
|
@ -89,7 +90,7 @@ class UserManager {
|
|||
void handleGeneralPresenceReceived(Swift::Presence::ref presence);
|
||||
void handleProbePresence(Swift::Presence::ref presence);
|
||||
void handleSubscription(Swift::Presence::ref presence);
|
||||
void handleRemoveTimeout(const std::string jid, bool reconnect);
|
||||
void handleRemoveTimeout(const std::string jid, User *user, bool reconnect);
|
||||
// void handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid);
|
||||
void addUser(User *user);
|
||||
|
||||
|
|
|
@ -32,31 +32,84 @@ class UserRegistry : public Swift::UserRegistry {
|
|||
public:
|
||||
UserRegistry(Config *cfg) {config = cfg;}
|
||||
~UserRegistry() {}
|
||||
bool isValidUserPassword(const Swift::JID& user, const Swift::SafeByteArray& password) {
|
||||
void isValidUserPassword(const Swift::JID& user, Swift::ServerFromClientSession *session, const Swift::SafeByteArray& password) {
|
||||
if (!CONFIG_STRING(config, "service.admin_username").empty() && user.getNode() == CONFIG_STRING(config, "service.admin_username")) {
|
||||
if (Swift::safeByteArrayToString(password) == CONFIG_STRING(config, "service.admin_password")) {
|
||||
onPasswordValid(user);
|
||||
session->handlePasswordValid();
|
||||
}
|
||||
else {
|
||||
onPasswordInvalid(user);
|
||||
session->handlePasswordInvalid();
|
||||
}
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
users[user.toBare().toString()] = Swift::safeByteArrayToString(password);
|
||||
std::string key = user.toBare().toString();
|
||||
|
||||
// Users try to connect twice
|
||||
if (users.find(key) != users.end()) {
|
||||
// Kill the first session if the second password is same
|
||||
if (Swift::safeByteArrayToString(password) == users[key].password) {
|
||||
Swift::ServerFromClientSession *tmp = users[key].session;
|
||||
users[key].session = session;
|
||||
tmp->handlePasswordInvalid();
|
||||
}
|
||||
else {
|
||||
session->handlePasswordInvalid();
|
||||
std::cout << "invalid " << session << "\n";
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::cout << "adding " << session << "\n";
|
||||
users[key].password = Swift::safeByteArrayToString(password);
|
||||
users[key].session = session;
|
||||
onConnectUser(user);
|
||||
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
void stopLogin(const Swift::JID& user, Swift::ServerFromClientSession *session) {
|
||||
std::cout << "stopping " << session << "\n";
|
||||
std::string key = user.toBare().toString();
|
||||
if (users.find(key) != users.end()) {
|
||||
if (users[key].session == session) {
|
||||
std::cout << "DISCONNECT USER\n";
|
||||
onDisconnectUser(user);
|
||||
users.erase(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onPasswordValid(const Swift::JID &user) {
|
||||
std::string key = user.toBare().toString();
|
||||
if (users.find(key) != users.end()) {
|
||||
users[key].session->handlePasswordValid();
|
||||
users.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
void onPasswordInvalid(const Swift::JID &user) {
|
||||
std::string key = user.toBare().toString();
|
||||
if (users.find(key) != users.end()) {
|
||||
users[key].session->handlePasswordInvalid();
|
||||
users.erase(key);
|
||||
}
|
||||
}
|
||||
|
||||
const std::string &getUserPassword(const std::string &barejid) {
|
||||
return users[barejid];
|
||||
return users[barejid].password;
|
||||
}
|
||||
|
||||
boost::signal<void (const Swift::JID &user)> onConnectUser;
|
||||
boost::signal<void (const Swift::JID &user)> onDisconnectUser;
|
||||
|
||||
|
||||
mutable std::map<std::string, std::string> users;
|
||||
private:
|
||||
typedef struct {
|
||||
std::string password;
|
||||
Swift::ServerFromClientSession *session;
|
||||
} Sess;
|
||||
|
||||
mutable std::map<std::string, Sess> users;
|
||||
mutable Config *config;
|
||||
};
|
||||
|
||||
|
|
23
src/user.cpp
23
src/user.cpp
|
@ -30,6 +30,9 @@
|
|||
#include "Swiften/Elements/MUCPayload.h"
|
||||
#include "log4cxx/logger.h"
|
||||
#include <boost/foreach.hpp>
|
||||
#include <execinfo.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace log4cxx;
|
||||
using namespace boost;
|
||||
|
@ -99,8 +102,28 @@ Swift::JID User::getJIDWithFeature(const std::string &feature) {
|
|||
return jid;
|
||||
}
|
||||
|
||||
static void
|
||||
print_trace (void)
|
||||
{
|
||||
void *array[80];
|
||||
size_t size;
|
||||
char **strings;
|
||||
size_t i;
|
||||
|
||||
size = backtrace (array, 80);
|
||||
strings = backtrace_symbols (array, size);
|
||||
|
||||
printf ("Obtained %zd stack frames.\n", size);
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
printf ("%s\n", strings[i]);
|
||||
|
||||
free (strings);
|
||||
}
|
||||
|
||||
void User::handlePresence(Swift::Presence::ref presence) {
|
||||
std::cout << "PRESENCE " << presence->getFrom().toString() << "\n";
|
||||
// print_trace();
|
||||
if (!m_connected) {
|
||||
// we are not connected to legacy network, so we should do it when disco#info arrive :)
|
||||
if (m_readyForConnect == false) {
|
||||
|
|
|
@ -55,6 +55,7 @@ UserManager::UserManager(Component *component, UserRegistry *userRegistry, Stora
|
|||
m_component->getStanzaChannel()->onPresenceReceived.connect(bind(&UserManager::handleGeneralPresenceReceived, this, _1));
|
||||
|
||||
m_userRegistry->onConnectUser.connect(bind(&UserManager::connectUser, this, _1));
|
||||
m_userRegistry->onDisconnectUser.connect(bind(&UserManager::disconnectUser, this, _1));
|
||||
// component->onDiscoInfoResponse.connect(bind(&UserManager::handleDiscoInfoResponse, this, _1, _2, _3));
|
||||
|
||||
m_removeTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(1);
|
||||
|
@ -187,16 +188,20 @@ void UserManager::handlePresence(Swift::Presence::ref presence) {
|
|||
Swift::Presence::ref highest = m_component->getPresenceOracle()->getHighestPriorityPresence(presence->getFrom().toBare());
|
||||
// There's no presence for this user, so disconnect
|
||||
if (!highest || (highest && highest->getType() == Swift::Presence::Unavailable)) {
|
||||
m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user->getJID().toBare().toString(), false));
|
||||
m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user->getJID().toBare().toString(), user, false));
|
||||
m_removeTimer->start();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UserManager::handleRemoveTimeout(const std::string jid, bool reconnect) {
|
||||
m_removeTimer->onTick.disconnect(boost::bind(&UserManager::handleRemoveTimeout, this, jid, reconnect));
|
||||
void UserManager::handleRemoveTimeout(const std::string jid, User *u, bool reconnect) {
|
||||
m_removeTimer->onTick.disconnect(boost::bind(&UserManager::handleRemoveTimeout, this, jid, u, reconnect));
|
||||
User *user = getUser(jid);
|
||||
if (user != u) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (user) {
|
||||
// Reconnect means that we're disconnecting this User instance from legacy network backend,
|
||||
// but we're going to connect it again in this call. Currently it's used only when
|
||||
|
@ -310,14 +315,28 @@ void UserManager::connectUser(const Swift::JID &user) {
|
|||
// Called by UserRegistry in server mode when user connects the server and wants
|
||||
// to connect legacy network
|
||||
if (m_users.find(user.toBare().toString()) != m_users.end()) {
|
||||
if (CONFIG_BOOL(m_component->getConfig(), "service.more_resources")) {
|
||||
m_userRegistry->onPasswordValid(user);
|
||||
}
|
||||
else {
|
||||
// Reconnect the user if more resources per one legacy network account are not allowed
|
||||
m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user.toBare().toString(), true));
|
||||
m_removeTimer->start();
|
||||
if (m_users[user.toBare().toString()]->isConnected()) {
|
||||
if (CONFIG_BOOL(m_component->getConfig(), "service.more_resources")) {
|
||||
m_userRegistry->onPasswordValid(user);
|
||||
}
|
||||
else {
|
||||
boost::shared_ptr<Swift::Message> msg(new Swift::Message());
|
||||
msg->setBody("You have signed on from another location.");
|
||||
msg->setTo(user);
|
||||
msg->setFrom(m_component->getJID());
|
||||
m_component->getStanzaChannel()->sendMessage(msg);
|
||||
m_userRegistry->onPasswordValid(user);
|
||||
m_component->onUserPresenceReceived.disconnect(bind(&UserManager::handlePresence, this, _1));
|
||||
dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->finishSession(user, boost::shared_ptr<Swift::Element>(new Swift::StreamError()), true);
|
||||
m_component->onUserPresenceReceived.connect(bind(&UserManager::handlePresence, this, _1));
|
||||
}
|
||||
}
|
||||
// }
|
||||
// else {
|
||||
// // Reconnect the user if more resources per one legacy network account are not allowed
|
||||
// m_removeTimer->onTick.connect(boost::bind(&UserManager::handleRemoveTimeout, this, user.toBare().toString(), true));
|
||||
// m_removeTimer->start();
|
||||
// }
|
||||
}
|
||||
else {
|
||||
// simulate initial available presence to start connecting this user.
|
||||
|
@ -325,9 +344,17 @@ void UserManager::connectUser(const Swift::JID &user) {
|
|||
response->setTo(m_component->getJID());
|
||||
response->setFrom(user);
|
||||
response->setType(Swift::Presence::Available);
|
||||
m_component->onUserPresenceReceived(response);
|
||||
dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->onPresenceReceived(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void UserManager::disconnectUser(const Swift::JID &user) {
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setTo(m_component->getJID());
|
||||
response->setFrom(user);
|
||||
response->setType(Swift::Presence::Unavailable);
|
||||
dynamic_cast<Swift::ServerStanzaChannel *>(m_component->getStanzaChannel())->onPresenceReceived(response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue