#include <chrono>
#include <ctime>
#include <iostream>
#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/detached.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/use_awaitable.hpp>
 
const std::string realm = "cppwamp.demo.time";
const std::string address = "localhost";
const short port = 54321u;
 
{
    
    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);
    }
}
 
std::tm getTime()
{
    auto t = std::time(nullptr);
    return *std::localtime(&t);
}
 
{
    using boost::asio::use_awaitable;
 
    (co_await session->connect(use_awaitable)).value();
    (co_await session->join(
Realm(realm), use_awaitable)).value();
    (co_await session->enroll(
Procedure(
"get_time"),
                              simpleRpc<std::tm>(&getTime),
                              use_awaitable)).value();
 
    boost::asio::steady_timer timer(co_await boost::asio::this_coro::executor);
    auto deadline = std::chrono::steady_clock::now();
    while (true)
    {
        deadline += std::chrono::seconds(1);
        timer.expires_at(deadline);
        co_await timer.async_wait(use_awaitable);
 
        auto t = std::time(nullptr);
        const std::tm* local = std::localtime(&t);
        (co_await session->publish(
Pub(
"time_tick").withArgs(*local),
                                   use_awaitable)).value();
        std::cout << "Tick: " << std::asctime(local) << "\n";
    }
}
 
int main()
{
    auto tcp = connector<Json>(ioctx, 
TcpHost(address, port));
 
    boost::asio::co_spawn(ioctx, service(session), boost::asio::detached);
    ioctx.run();
    return 0;
}