CppWAMP
C++11 client library for the WAMP protocol
examples/stacklesstimeclient/main.cpp
/*------------------------------------------------------------------------------
Copyright Butterfly Energy Systems 2022.
Distributed under the Boost Software License, Version 1.0.
http://www.boost.org/LICENSE_1_0.txt
------------------------------------------------------------------------------*/
//******************************************************************************
// Example WAMP service consumer app using stackless coroutines.
//******************************************************************************
#include <ctime>
#include <iostream>
#include <boost/variant2.hpp>
#include <cppwamp/json.hpp>
#include <cppwamp/tcp.hpp>
#include <boost/asio/yield.hpp>
const std::string realm = "cppwamp.demo.time";
const std::string address = "localhost";
const short port = 12345u;
//------------------------------------------------------------------------------
namespace wamp
{
// Convert a std::tm to/from an object variant.
template <typename TConverter>
void convert(TConverter& conv, std::tm& t)
{
conv ("sec", t.tm_sec)
("min", t.tm_min)
("hour", t.tm_hour)
("mday", t.tm_mday)
("mon", t.tm_mon)
("year", t.tm_year)
("wday", t.tm_wday)
("yday", t.tm_yday)
("isdst", t.tm_isdst);
}
}
//------------------------------------------------------------------------------
void onTimeTick(std::tm time)
{
std::cout << "The current time is: " << std::asctime(&time) << std::endl;
}
//------------------------------------------------------------------------------
// This variant type is necessary for TimeService::operator() to resume Session
// operations emitting different result types. This makes Boost stackless
// coroutines awkward to use with CppWAMP, but this example demonstrates
// it is still possible.
//------------------------------------------------------------------------------
using Aftermath = boost::variant2::variant<
boost::variant2::monostate,
//------------------------------------------------------------------------------
// Visitor that checks the success of any of the result types passed to the
// coroutine.
//------------------------------------------------------------------------------
struct AftermathChecker
{
void operator()(boost::variant2::monostate) const {}
template <typename T>
void operator()(const wamp::ErrorOr<T>& result) const
{
result.value();
}
};
//------------------------------------------------------------------------------
class TimeClient : boost::asio::coroutine
{
public:
explicit TimeClient(wamp::Session::Ptr session)
: session_(session)
{}
void operator()(Aftermath aftermath = {})
{
boost::variant2::visit(AftermathChecker{}, aftermath);
std::tm time;
reenter (this)
{
yield session_->connect(*this);
std::cout << "Connected via "
<< boost::variant2::get<1>(aftermath).value() << std::endl;
yield session_->join(wamp::Realm(realm), *this);
std::cout << "Joined, SessionId="
<< boost::variant2::get<2>(aftermath).value().id()
<< std::endl;
yield session_->call(wamp::Rpc("get_time"), *this);
time = boost::variant2::get<3>(aftermath).value()[0].to<std::tm>();
std::cout << "The current time is: " << std::asctime(&time)
<< std::endl;
yield session_->subscribe(wamp::Topic("time_tick"),
wamp::simpleEvent<std::tm>(&onTimeTick),
*this);
}
}
private:
// The session object must be stored as a shared pointer due to
// TimeClient getting copied around.
};
//------------------------------------------------------------------------------
int main()
{
using namespace wamp;
AsioContext ioctx;
auto tcp = connector<Json>(ioctx, TcpHost(address, port));
auto session = Session::create(ioctx, tcp);
TimeClient client(session);
client();
ioctx.run();
return 0;
}
wamp::Session::create
static Ptr create(AnyIoExecutor exec, const Connector::Ptr &connector)
Creates a new Session instance.
Definition: session.ipp:22
session.hpp
Contains the asynchronous session API used by a client peer in WAMP applications.
wamp::Realm
Realm URI and other options contained within WAMP HELLO messages.
Definition: peerdata.hpp:59
wamp::Session::Ptr
std::shared_ptr< Session > Ptr
Shared pointer to a Session.
Definition: session.hpp:117
wamp::Topic
Provides the topic URI and other options contained within WAMP ‘SUBSCRIBE’ messages.
Definition: peerdata.hpp:331
wamp::TcpHost
Contains TCP host address information, as well as other socket options.
Definition: tcphost.hpp:103
wamp
Definition: anyhandler.hpp:36
unpacker.hpp
Contains utilities for unpacking positional arguments passed to event slots and call slots.
json.hpp
Contains the JSON codec.
wamp::Rpc
Contains the procedure URI, options, and payload contained within WAMP CALL messages.
Definition: peerdata.hpp:535
tcp.hpp
Contains facilities for creating TCP transport connectors.
wamp::ErrorOr
Minimalistic implementation of std::expected<T, std::error_code>
Definition: erroror.hpp:128
variant.hpp
Contains the declaration of Variant and other closely related types/functions.
wamp::convert
void convert(TConverter &c, TValue &val)
General function for converting custom types to/from Variant.
Definition: variant.hpp:709
wamp::AsioContext
boost::asio::io_context AsioContext
Queues and runs I/O completion handlers.
Definition: asiodefs.hpp:34