WAMP for C++ on Boost/ASIO.
AutobahnC++ is a subproject of Autobahn which provides a C++ WAMP implementation that is able to talk WAMP over stdio
pipes.
- Caller
- Callee
- Publisher
- Subscriber
AutobahnC++ is open-source, licensed under the Boost Software License.
The API and implementation make use of modern C++ 11 and new asynchronous idioms using (upcoming) features of the standard C++ library, in particular Futures, Continuations and Lambdas.
Continuations are one way of managing control flow in an asynchronous program. Other styles include: asynchronous Callbacks, Coroutines (
yield
orawait
), Actors (Erlang/OTP, Scala/Akka or Rust) and Transactional memory.
AutobahnC++ supports running WAMP (rawsocket-msgpack
) over TCP(-TLS), Unix domain sockets or pipes (stdio
). The library is "header-only", light-weight (< 2k code lines) and depends on the following:
- C++11 compiler
boost::future
boost::asio
msgpack-c
WebSocket++
For getting help, questions or feedback, get in touch on the mailing list, Twitter or IRC #autobahn
(Freenode).
Here is how programming with C++ and AutobahnC++ looks like.
Calling a remote Procedure
auto c1 = session.call("com.mathservice.add2", std::make_tuple(23, 777))
.then([&](boost::future<wamp_call_result> result) {
std::cout << "Got call result " << result.get().argument<uint64_t>(0) << std::endl;
});
Registering a remoted Procedure
auto r1 = session.provide("com.myapp.cpp.square",
[](autobahn::wamp_invocation invocation) {
std::cout << "Procedure is invoked .." << endl;
uint64_t x = invocation->argument<uint64_t>(0);
return x * x;
})
.then([](boost::future<autobahn::wamp_registration> reg) {
std::cout << "Registered with ID " << reg.get().id() << std::endl;
});
Publishing an Event
session.publish("com.myapp.topic2", std::make_tuple(23, true, std::string("hello")));
Publishing an Event (acknowledged)
auto opts = PublishOptions();
opts.acknowledge = True;
session.publish("com.myapp.topic2", std::make_tuple(23, true, std::string("hello")), opts)
.then([](boost::future<autobahn::wamp_publication> pub) {
std::cout << "Published with ID " << pub.get().id() << std::endl;
});
Subscribing to a Topic
auto s1 = session.subscribe("com.myapp.topic1",
[](const autobahn::wamp_event& event) {
std::cout << "Got event: " << event.argument<uint64_t>(0) << std::endl;
})
.then([](boost::future<autobahn::wamp_subscription> sub) {
std::cout << "Subscribed with ID " << sub.get().id() << std::endl;
});
Here is JavaScript running in Chrome call into C++ running on command line. Both are connected via a WAMP router, in this case Autobahn|Python based.
The Autobahn|Cpp repository contains a number of examples that demonstrate all 4 basic patterns of using WAMP. There are also examples for WAMP-CRA and Unix domain sockets.
Notes
- The library code is written in standard C++ 11. Target toolchains currently include clang and gcc. Support for MSVC is tracked on this issue.
- While C++ 11 includes
std::future
in the standard library, this lacks continuations.boost::future.then
allows attaching continuations to futures as outlined in the proposal here. This feature will come to standard C++, but probably not before 2017 (see C++ Standardisation Roadmap)- Support for
when_all
andwhen_any
as described in above proposal depends on Boost 1.56 or higher.- The library and example programs were tested and developed with clang 3.4, libc++ and Boost trunk/1.56 on an Ubuntu 13.10 x86-64 bit system. It also works with gcc 4.8, libstdc++ and Boost trunk/1.56. Your mileage with other versions of the former may vary, but we accept PRs;)
Install some libs and build tools (these are for Ubuntu):
sudo apt-get install -y libbz2-dev libssl-dev cmake
If you want to work with Clang (rather than GCC), install clang and libc++ (these are for Ubuntu):
sudo apt-get install -y clang libc++1 libc++-dev
Then make Clang available:
oberstet@corei7ub1310:~$ sudo update-alternatives --config c++
[sudo] password for oberstet:
Es gibt 3 Auswahlmöglichkeiten für die Alternative c++ (welche /usr/bin/c++ bereitstellen).
Auswahl Pfad Priorität Status
------------------------------------------------------------
* 0 /usr/bin/g++ 20 Auto-Modus
1 /usr/bin/clang++ 10 manueller Modus
2 /usr/bin/clang++-libc++ 5 manueller Modus
3 /usr/bin/g++ 20 manueller Modus
Drücken Sie die Eingabetaste, um die aktuelle Wahl[*] beizubehalten,
oder geben Sie die Auswahlnummer ein: 1
update-alternatives: /usr/bin/clang++ wird verwendet, um /usr/bin/c++ (c++) im manueller Modus bereitzustellen
Most of the time, your distro's Boost libraries will be outdated (unless you're using Arch or Homebrew). Don't waste time with those: to build the latest Boost 1.63 (current release as of 2016/12) from sources.
Get Boost 1.63:
cd ~
wget https://sourceforge.net/projects/boost/files/boost/1.63.0/boost_1_63_0.tar.bz2
tar xvjf boost_1_63_0.tar.bz2
cd boost_1_63_0
To build using Clang:
./bootstrap.sh --with-toolset=clang
./b2 toolset=clang cxxflags="-stdlib=libc++" linkflags="-stdlib=libc++" -j 4
To build using GCC:
./bootstrap.sh --with-toolset=gcc
./b2 toolset=gcc -j 4 install --prefix=/usr/local
Note: The
-j 4
option will allow use of 4 cores for building.
Then add the following to your ~/.profile
or ~/.bashrc
:
export BOOST_ROOT=${HOME}/boost_1_63_0
export LD_LIBRARY_PATH=${BOOST_ROOT}/stage/lib:${LD_LIBRARY_PATH}
Get MsgPack-C and install:
cd ~
git clone https://github.com/msgpack/msgpack-c.git
cd msgpack-c
git checkout cpp-1.4.2
cmake -DMSGPACK_CXX11=ON .
make install
On FreeBSD, you need to
pkg install autotools
and invokegmake
instead ofmake
.
Get WebSocket++ and install:
cd ~
git clone https://github.com/zaphoyd/websocketpp.git
cd websocketpp
cmake .
make install
To get AutobahnC++ library and examples, clone the repo
cd ~
git clone https://github.com/crossbario/autobahn-cpp.git
cd autobahn-cpp
cp -r autobahn/ /usr/local/include/
The library is "header-only", means there isn't anything to compile or build. Just include the relevant headers.
apt-get install scons
cd $HOME/autobahn-cpp/examples
scons
Click here for the Autobahn|Cpp reference documentation.
Get in touch on IRC #autobahn
on chat.freenode.net
, follow us on Twitter or join the mailing list.
- ASIO C++11 Examples
- Using Asio with C++11
- C++17: I See a Monad in Your Future!
- Boost Thread
- Boost Issue: when_all
- Boost Issue. when_any
- Boost Issue: future fires twice
- Boost C++ 1y
- Asynchronous API in C++ and the Continuation Monad
[]
Capture nothing (or, a scorched earth strategy?)[&]
Capture any referenced variable by reference[=]
Capture any referenced variable by making a copy[=, &foo]
Capture any referenced variable by making a copy, but capture variablefoo
by reference[bar]
Capturebar
by making a copy; don't copy anything else[this]
Capture the this pointer of the enclosing class