Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve Participant List, Send Message to Channel and Real JID lookup of participants proxy JID #89

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Retrieve Participant List, Send Message to Channel and Real JID looku…
…p of participants proxy JID

Adds sending message to channel and server forwarding message to participants and reflecting back message to originator.
Adds JID lookup request by client and corresponding response by MIX Mock Server.
Adds requesting participant list by client and response from mock server.

License:
This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.

Change-Id: I53091a13422598f200134ac08cc3095cd140b792
  • Loading branch information
tarun018 committed Aug 24, 2017
commit bedefc2f0707ac6beb17a17bf6479befbf40c1ca
235 changes: 218 additions & 17 deletions Limber/MIXMockServer.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Swiften/Client/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender);
discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories->getCryptoProvider());

mixRegistry = std::make_unique<MIXRegistry>(getJID(), getIQRouter(), getRoster());
mixRegistry = std::make_unique<MIXRegistry>(getJID(), getIQRouter(), getRoster(), getStanzaChannel());

mucRegistry = new MUCRegistry();
mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry);
Expand Down
86 changes: 82 additions & 4 deletions Swiften/Examples/MIXListAndJoin/MIXListAndJoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/ErrorPayload.h>
#include <Swiften/Elements/MIXParticipant.h>
#include <Swiften/Elements/MIXPayload.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/PubSub.h>
#include <Swiften/Elements/PubSubItems.h>
#include <Swiften/EventLoop/SimpleEventLoop.h>
#include <Swiften/JID/JID.h>
#include <Swiften/MIX/MIX.h>
Expand All @@ -40,8 +44,82 @@ static MIXImpl::ref mix;
static JID mixChannelJID;
static JID mixServiceDomain;
static std::unordered_set<std::string> supportedNodes;
static std::unordered_set<std::string> participants;
static MIXRegistry* mixRegistry_;

static void handleMessageReceived(Message::ref message) {
if (auto mixPayload = message->getPayload<MIXPayload>()) {
if (mixPayload->getSubmissionID()) {
SWIFT_LOG(debug) << "Ignoring the replicated message" << std::endl;
return;
} else if (message->getFrom().toBare() == mixChannelJID) {
std::cout << "[ " << mixChannelJID << " ] " << message->getFrom().getResource() << ": " << message->getBody().get_value_or("") << std::endl;
}
}
}

static void handleLookupResponse(std::shared_ptr<PubSub> payload, ErrorPayload::ref error) {
if (error) {
return;
}

std::cout << "Lookup of participant in channel " << mixChannelJID << std::endl;
int participantCount = 0;
auto itemsPayload = std::dynamic_pointer_cast<PubSubItems>(payload->getPayload());
SWIFT_LOG_ASSERT(itemsPayload->getNode() == MIX::JIDMapNode, warning);

auto items = itemsPayload->getItems();

for(auto item : items) {
SWIFT_LOG_ASSERT(item->getData().size() == static_cast<int>(1), warning);
participantCount++;
auto mixParticipant = std::dynamic_pointer_cast<MIXParticipant>(item->getData()[0]);
if (auto realJID = mixParticipant->getJID()) {
std::cout << "\t" << participantCount << ". " << item->getID() << " - " << *realJID << std::endl;
}
}

std::cout << std::endl;

// Sending message to channel
mix->sendMessage("Hello, I am here! " + client->getJID().getNode());

// Leave channel.
// Commented to test the sync between different clients of same user.
// mixRegistry_->leaveChannel(mixChannelJID);
}

static void handleParticipantsReceived(std::shared_ptr<PubSub> payload, ErrorPayload::ref error) {
if (error) {
return;
}

std::cout << "Participants of channel " << mixChannelJID << std::endl;
int participantCount = 0;
auto itemsPayload = std::dynamic_pointer_cast<PubSubItems>(payload->getPayload());
SWIFT_LOG_ASSERT(itemsPayload->getNode() == MIX::ParticipantsNode, warning);

auto items = itemsPayload->getItems();

for(auto item : items) {
SWIFT_LOG_ASSERT(item->getData().size() == static_cast<int>(1), warning);
participantCount++;
auto mixParticipant = std::dynamic_pointer_cast<MIXParticipant>(item->getData()[0]);
std::cout << "\t" << participantCount << ". " << item->getID() << std::endl;
participants.insert(item->getID());
}

if (participantCount == 0) {
std::cout << "No participants already joined." << std::endl;
}

std::cout << std::endl;

//Perform JID lookups.
mix->onLookupResponse.connect(&handleLookupResponse);
mix->lookupJID(participants);
}

static void handleChannelJoined(const JID& jid) {
// Successfully joined the channel.
assert(mixRegistry_);
Expand All @@ -51,14 +129,13 @@ static void handleChannelJoined(const JID& jid) {

//trying to rejoin the same channel joined. Should not send the iq request. Will print a warning.
mixRegistry_->joinChannel(mixChannelJID, supportedNodes);
std::cout << std::endl;

mix = mixRegistry_->getMIXInstance(jid);

mix->onParticipantResponse.connect(&handleParticipantsReceived);
// Can perform other functions with MIXImpl object: mix.
mix->requestParticipantList();

// Finally leave channel.
// This is commented to check the sync between different users using different clients(resources) to connect.
//mixRegistry_->leaveChannel(mixChannelJID);
}

static void handleChannelJoinFailed(ErrorPayload::ref /*error*/) {
Expand Down Expand Up @@ -179,6 +256,7 @@ int main(int argc, char* argv[]) {

client->onConnected.connect(&handleConnected);
client->onDisconnected.connect(&handleDisconnected);
client->onMessageReceived.connect(&handleMessageReceived);

std::cout << "Connecting..." << std::flush;
client->connect(options);
Expand Down
21 changes: 21 additions & 0 deletions Swiften/MIX/MIX.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
#include <Swiften/Base/API.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/PubSub.h>
#include <Swiften/Elements/PubSubItem.h>
#include <Swiften/Elements/PubSubItems.h>
#include <Swiften/Elements/MIXUpdateSubscription.h>
#include <Swiften/Elements/MIXUserPreference.h>
#include <Swiften/Elements/ErrorPayload.h>
Expand Down Expand Up @@ -52,9 +56,26 @@ namespace Swift {
*/
virtual void updatePreferences(Form::ref form) = 0;

/**
* Sends a message to channel with given body.
*/
virtual void sendMessage(const std::string &body) = 0;

/**
* Look up real JIDs from proxy JIDs in JIDVisible or JIDMaybeVisible Rooms.
*/
virtual void lookupJID(const std::unordered_set<std::string>& proxyJIDs) = 0;

/**
* Retrieves the list of participants of the channel.
*/
virtual void requestParticipantList() = 0;

public:
boost::signals2::signal<void (MIXUpdateSubscription::ref /* updateResponse */, ErrorPayload::ref /* updateError */)> onSubscriptionUpdateResponse;
boost::signals2::signal<void (Form::ref /* preferencesForm */, ErrorPayload::ref /* failedConfiguration */)> onPreferencesFormResponse;
boost::signals2::signal<void (MIXUserPreference::ref /* userPreferenceResponse */, ErrorPayload::ref /* failedUpdate */)> onPreferencesUpdateResponse;
boost::signals2::signal<void (std::shared_ptr<PubSub> /* responsePubSub */, ErrorPayload::ref /* lookupError */)> onLookupResponse;
boost::signals2::signal<void (std::shared_ptr<PubSub> /* responsePubSub */, ErrorPayload::ref /* lookupError */)> onParticipantResponse;
};
}
49 changes: 48 additions & 1 deletion Swiften/MIX/MIXImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Swift {

MIXImpl::MIXImpl(const JID& ownJID, const JID& channelJID, IQRouter* iqRouter) : ownJID_(ownJID), channelJID_(channelJID), iqRouter_(iqRouter) {
MIXImpl::MIXImpl(const JID& ownJID, const JID& channelJID, IQRouter* iqRouter, StanzaChannel* stanzaChannel) : ownJID_(ownJID), channelJID_(channelJID), iqRouter_(iqRouter), stanzaChannel_(stanzaChannel) {

}

Expand Down Expand Up @@ -60,4 +60,51 @@ void MIXImpl::updatePreferences(Form::ref form) {
request->send();
}

void MIXImpl::sendMessage(const std::string &body) {
auto message = std::make_shared<Message>();
message->setTo(channelJID_);
message->setType(Message::Groupchat);
message->setBody(body);
message->setID(idGenerator.generateID());
stanzaChannel_->sendMessage(message);
}

void MIXImpl::lookupJID(const std::unordered_set<std::string>& proxyJIDs) {
auto itemsPayload = std::make_shared<PubSubItems>();
itemsPayload->setNode(MIX::JIDMapNode);

for (auto proxyJID : proxyJIDs) {
auto item = std::make_shared<PubSubItem>();
item->setID(std::string(proxyJID));
itemsPayload->addItem(item);
}

auto pubSubPayload = std::make_shared<PubSub>();
pubSubPayload->setPayload(itemsPayload);

auto request = std::make_shared<GenericRequest<PubSub>>(IQ::Get, channelJID_, pubSubPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handleJIDLookupResponse, this, _1, _2));
request->send();
}

void MIXImpl::handleJIDLookupResponse(std::shared_ptr<PubSub> payload, ErrorPayload::ref error) {
onLookupResponse(payload, error);
}

void MIXImpl::requestParticipantList() {
auto itemsPayload = std::make_shared<PubSubItems>();
itemsPayload->setNode(MIX::ParticipantsNode);

auto pubSubPayload = std::make_shared<PubSub>();
pubSubPayload->setPayload(itemsPayload);

auto request = std::make_shared<GenericRequest<PubSub>>(IQ::Get, channelJID_, pubSubPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MIXImpl::handleParticipantList, this, _1, _2));
request->send();
}

void MIXImpl::handleParticipantList(std::shared_ptr<PubSub> payload, ErrorPayload::ref error) {
onParticipantResponse(payload, error);
}

}
14 changes: 13 additions & 1 deletion Swiften/MIX/MIXImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

#include <Swiften/MIX/MIX.h>

#include <Swiften/Base/IDGenerator.h>

namespace Swift {
class StanzaChannel;
class IQRouter;
Expand All @@ -17,7 +19,7 @@ namespace Swift {
using ref = std::shared_ptr<MIXImpl>;

public:
MIXImpl(const JID& ownJID, const JID& channelJID, IQRouter* iqRouter);
MIXImpl(const JID& ownJID, const JID& channelJID, IQRouter* iqRouter, StanzaChannel* stanzaChannel);
virtual ~MIXImpl();

/**
Expand All @@ -40,14 +42,24 @@ namespace Swift {

virtual void updatePreferences(Form::ref form) override;

virtual void sendMessage(const std::string& body) override;

virtual void lookupJID(const std::unordered_set<std::string>& proxyJIDs) override;

virtual void requestParticipantList() override;

private:
void handleUpdateSubscriptionResponse(MIXUpdateSubscription::ref, ErrorPayload::ref);
void handlePreferencesFormReceived(MIXUserPreference::ref, ErrorPayload::ref);
void handlePreferencesResultReceived(MIXUserPreference::ref /*payload*/, ErrorPayload::ref error);
void handleJIDLookupResponse(std::shared_ptr<PubSub>, ErrorPayload::ref error);
void handleParticipantList(std::shared_ptr<PubSub>, ErrorPayload::ref error);

private:
JID ownJID_;
JID channelJID_;
IQRouter* iqRouter_;
StanzaChannel* stanzaChannel_;
IDGenerator idGenerator;
};
}
6 changes: 3 additions & 3 deletions Swiften/MIX/MIXRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@

namespace Swift {

MIXRegistry::MIXRegistry(const JID& ownJID, IQRouter* iqRouter, XMPPRoster* xmppRoster) : ownJID_(ownJID), iqRouter_(iqRouter), xmppRoster_(xmppRoster) {
MIXRegistry::MIXRegistry(const JID& ownJID, IQRouter* iqRouter, XMPPRoster* xmppRoster, StanzaChannel* stanzaChannel) : ownJID_(ownJID), iqRouter_(iqRouter), xmppRoster_(xmppRoster), stanzaChannel_(stanzaChannel) {
initialRosterPopulationConnection_ = xmppRoster_->onInitialRosterPopulated.connect([=] {
SWIFT_LOG(debug) << "Syncing with roster items. " << std::endl;
for (auto item : xmppRoster_->getItems()) {
if (item.isMIXChannel()) {
auto i = entries_.find(item.getJID());
if (i == entries_.end()) {
entries_.insert(std::make_pair(item.getJID(), std::make_shared<MIXImpl>(ownJID_, item.getJID(), iqRouter_)));
entries_.insert(std::make_pair(item.getJID(), std::make_shared<MIXImpl>(ownJID_, item.getJID(), iqRouter_, stanzaChannel_)));
}
}
}
Expand Down Expand Up @@ -66,7 +66,7 @@ void MIXRegistry::handleJIDAdded(const JID& jid) {
if (xmppRoster_->isMIXChannel(jid)) {
auto i = entries_.find(jid);
if (i == entries_.end()) {
entries_.insert(std::make_pair(jid, std::make_shared<MIXImpl>(ownJID_, jid, iqRouter_)));
entries_.insert(std::make_pair(jid, std::make_shared<MIXImpl>(ownJID_, jid, iqRouter_, stanzaChannel_)));
}
onChannelJoined(jid);
}
Expand Down
3 changes: 2 additions & 1 deletion Swiften/MIX/MIXRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace Swift {
using MIXInstanceMap = std::map<JID, MIXImpl::ref>;

public:
MIXRegistry(const JID& ownJID, IQRouter* iqRouter, XMPPRoster* xmppRoster);
MIXRegistry(const JID& ownJID, IQRouter* iqRouter, XMPPRoster* xmppRoster, StanzaChannel* stanzaChannel);

~MIXRegistry();

Expand Down Expand Up @@ -72,6 +72,7 @@ namespace Swift {
JID ownJID_;
IQRouter* iqRouter_;
XMPPRoster* xmppRoster_;
StanzaChannel* stanzaChannel_;
MIXInstanceMap entries_;
boost::signals2::scoped_connection initialRosterPopulationConnection_;
};
Expand Down
2 changes: 1 addition & 1 deletion Swiften/MIX/UnitTest/MIXRegistryTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class MIXRegistryTest : public ::testing::Test {
}

MIXRegistry* getMIXRegistry() {
mixRegistry_ = new MIXRegistry(ownJID_, router_, xmppRoster_);
mixRegistry_ = new MIXRegistry(ownJID_, router_, xmppRoster_, channel_);
mixRegistry_->onChannelJoined.connect(boost::bind(&MIXRegistryTest::handleChannelJoined, this, _1));
mixRegistry_->onChannelJoinFailed.connect(boost::bind(&MIXRegistryTest::handleJoinFailed, this, _1));
mixRegistry_->onChannelLeft.connect(boost::bind(&MIXRegistryTest::handleChannelLeft, this, _1));
Expand Down