This commit is contained in:
parent
7078c25c2a
commit
5c250ac434
4 changed files with 60 additions and 23 deletions
|
@ -8,6 +8,8 @@
|
|||
#include <larra/printer_stream.hpp>
|
||||
#include <print>
|
||||
|
||||
namespace iq = larra::xmpp::iq;
|
||||
|
||||
auto Coroutine() -> boost::asio::awaitable<void> {
|
||||
SPDLOG_INFO("Connecting client...");
|
||||
|
||||
|
@ -15,20 +17,28 @@ auto Coroutine() -> boost::asio::awaitable<void> {
|
|||
auto client = co_await larra::xmpp::client::CreateClient<larra::xmpp::PrintStream<boost::asio::ip::tcp::socket>>(
|
||||
larra::xmpp::PlainUserAccount{.jid = {.username = "test1", .server = "localhost"}, .password = "test1"},
|
||||
{.useTls = larra::xmpp::client::Options::kNever});
|
||||
/*
|
||||
|
||||
// TODO(unknown):
|
||||
// rfc6120 7.1
|
||||
// After a client authenticates with a server,
|
||||
// it MUST bind a specific resource to the stream so that the server can properly address the client.
|
||||
|
||||
co_await std::visit(
|
||||
[](auto& client) -> boost::asio::awaitable<void> {
|
||||
co_await client.UpdateListOfContacts();
|
||||
},
|
||||
client);
|
||||
|
||||
// rfc6120 2.2
|
||||
// Upon authenticating with a server and binding a resource (thus becoming a connected resource as defined in [XMPP‑CORE]),
|
||||
// a client SHOULD request the roster before sending initial presence
|
||||
co_await std::visit(
|
||||
[](auto& client) -> boost::asio::awaitable<void> {
|
||||
SPDLOG_INFO("Send presence: Available");
|
||||
co_await client.Send(larra::xmpp::presence::c2s::Available{});
|
||||
},
|
||||
client);
|
||||
*/
|
||||
|
||||
std::visit(
|
||||
[](auto& client) -> boost::asio::awaitable<void> {
|
||||
co_await client.UpdateListOfContacts();
|
||||
},
|
||||
client);
|
||||
} catch(const std::exception& err) {
|
||||
SPDLOG_ERROR("{}", err.what());
|
||||
co_return;
|
||||
|
|
|
@ -79,10 +79,16 @@ struct Client {
|
|||
|
||||
auto UpdateListOfContacts() -> boost::asio::awaitable<void> {
|
||||
SPDLOG_INFO("Send IQ: Get::Roster");
|
||||
co_await this->Send(::iq::GetRoster{});
|
||||
co_await std::visit(
|
||||
[&](auto&& query) -> boost::asio::awaitable<void> {
|
||||
co_await this->Send(query);
|
||||
}, ::iq::MakeGetRoster(jid));
|
||||
|
||||
|
||||
::iq::ResultRoster roster = co_await connection.template Read<::iq::ResultRoster>();
|
||||
for (const auto& jid : roster.payload.items) {
|
||||
//IqRoster roster = co_await connection.template Read<IqRoster>();
|
||||
//const auto& roster_result = std::get<::iq::ResultRoster>(roster);
|
||||
::iq::ResultRoster roster_result = co_await connection.template Read<::iq::ResultRoster>();
|
||||
for (const auto& jid : roster_result.payload.items) {
|
||||
SPDLOG_INFO("\t'{}'", ToString(jid));
|
||||
}
|
||||
co_return;
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <larra/serialization.hpp>
|
||||
#include <larra/stream_error.hpp>
|
||||
#include <larra/utils.hpp>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
namespace larra::xmpp {
|
||||
|
@ -11,6 +12,8 @@ namespace iq {
|
|||
template <auto& Name, typename PayloadType>
|
||||
struct BaseImplWithPayload {
|
||||
std::string id;
|
||||
std::optional<std::string> from{};
|
||||
std::optional<std::string> to{};
|
||||
PayloadType payload;
|
||||
static const inline std::string kName = Name;
|
||||
static constexpr auto kDefaultName = "iq";
|
||||
|
@ -19,16 +22,32 @@ struct BaseImplWithPayload {
|
|||
[[nodiscard]] constexpr auto Id(this Self&& self, std::string id) -> std::decay_t<Self> {
|
||||
return utils::FieldSetHelper::With<"id", BaseImplWithPayload>(std::forward<Self>(self), std::move(id));
|
||||
}
|
||||
template <typename Self>
|
||||
[[nodiscard]] constexpr auto To(this Self&& self, std::string to) -> std::decay_t<Self> {
|
||||
return utils::FieldSetHelper::With<"to", BaseImplWithPayload>(std::forward<Self>(self), std::move(to));
|
||||
}
|
||||
template <typename Self>
|
||||
[[nodiscard]] constexpr auto From(this Self&& self, std::string from) -> std::decay_t<Self> {
|
||||
return utils::FieldSetHelper::With<"from", BaseImplWithPayload>(std::forward<Self>(self), std::move(from));
|
||||
}
|
||||
template <typename NewPayloadType, typename Self>
|
||||
[[nodiscard]] constexpr auto Payload(this Self&& self, NewPayloadType value) {
|
||||
return utils::FieldSetHelper::With<"payload", BaseImplWithPayload, false>(std::forward<Self>(self), std::move(value));
|
||||
}
|
||||
friend constexpr auto operator<<(xmlpp::Element* element, const BaseImplWithPayload& self) {
|
||||
element->set_attribute("id", self.id);
|
||||
|
||||
if (self.to) {
|
||||
element->set_attribute("to", *self.to);
|
||||
}
|
||||
if (self.from) {
|
||||
element->set_attribute("from", *self.from);
|
||||
}
|
||||
element->set_attribute("type", kName);
|
||||
using S = Serialization<PayloadType>;
|
||||
S::Serialize(element->add_child_element(S::kDefaultName, S::kPrefix), self.payload);
|
||||
}
|
||||
|
||||
[[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> BaseImplWithPayload {
|
||||
auto node = element->get_attribute("type");
|
||||
if(!node) {
|
||||
|
@ -41,6 +60,9 @@ struct BaseImplWithPayload {
|
|||
if(!idNode) {
|
||||
throw std::runtime_error("Not found attribute id for parse Iq");
|
||||
}
|
||||
auto from = element->get_attribute("from");
|
||||
auto to = element->get_attribute("to");
|
||||
|
||||
|
||||
using S = Serialization<PayloadType>;
|
||||
auto payload = element->get_first_child(S::kDefaultName);
|
||||
|
@ -51,7 +73,11 @@ struct BaseImplWithPayload {
|
|||
if(!payload2) {
|
||||
throw std::runtime_error("Invalid payload for parse Iq");
|
||||
}
|
||||
return {.id = idNode->get_value(), .payload = S::Parse(payload2)};
|
||||
return {
|
||||
.id = idNode->get_value(),
|
||||
.from = (from ? std::optional{from->get_value()} : std::nullopt),
|
||||
.to = (to ? std::optional{to->get_value()} : std::nullopt),
|
||||
.payload = S::Parse(payload2)};
|
||||
}
|
||||
};
|
||||
static constexpr auto kGetName = "get";
|
||||
|
|
|
@ -16,6 +16,7 @@ struct Roster {
|
|||
std::vector<BareJid> items;
|
||||
|
||||
friend constexpr auto operator<<(xmlpp::Element* element, const Roster& roster) {
|
||||
element->set_attribute("xmlns", "jabber:iq:roster");
|
||||
}
|
||||
[[nodiscard]] static constexpr auto Parse(xmlpp::Element* element) -> Roster {
|
||||
const auto& item_nodes = element->get_children("item");
|
||||
|
@ -41,21 +42,15 @@ struct Roster {
|
|||
| std::ranges::to<std::vector<BareJid>>()};
|
||||
}
|
||||
|
||||
/*
|
||||
friend constexpr auto operator<<(std::iostream& io, const Roster& roster) {
|
||||
for (const auto& jid : roster.items) {
|
||||
io << ToString(jid) << ' ';
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
using GetRoster = Get<Roster>;
|
||||
using ResultRoster = Result<Roster>;
|
||||
using IqRoster = Iq<Roster>;
|
||||
|
||||
auto MakeGetRoster(const BareJid& jid) {
|
||||
IqRoster iq_roster{std::in_place_type<GetRoster>, GetRoster{.id="1", .from=ToString(jid), .payload=Roster{}}};
|
||||
return iq_roster;
|
||||
}
|
||||
|
||||
} // namespace larra::xmpp::iq
|
||||
|
||||
namespace larra::xmpp {
|
||||
using IqRoster = Iq<iq::Roster>;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue