From 366bae00016bfbfdd354ab010555c2927505b2b2 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Thu, 13 Oct 2016 14:35:32 +0200 Subject: Second big network rewrite. This time without the ugly SFINAE hack to restrict sending and receiving on Senders and Receivers respectively. Replaced this hack with private inheritance and using declerations. Also renamed receive to async_receive to better reflect the behaviour. --- libcmix-network/CMakeLists.txt | 3 +- libcmix-network/client.hpp | 4 +- libcmix-network/protobufclient.hpp | 141 +++++-------------------------------- 3 files changed, 20 insertions(+), 128 deletions(-) (limited to 'libcmix-network') diff --git a/libcmix-network/CMakeLists.txt b/libcmix-network/CMakeLists.txt index c64c8b7..ee0f6e9 100644 --- a/libcmix-network/CMakeLists.txt +++ b/libcmix-network/CMakeLists.txt @@ -26,8 +26,7 @@ target_link_libraries(cmix-network PUBLIC Boost::system PUBLIC ${CMAKE_THREAD_LIBS_INIT} PRIVATE cmix - PRIVATE log - PRIVATE cmix-protobuf + PUBLIC log ) if(WIN32) diff --git a/libcmix-network/client.hpp b/libcmix-network/client.hpp index 7b88282..4990667 100644 --- a/libcmix-network/client.hpp +++ b/libcmix-network/client.hpp @@ -102,10 +102,10 @@ public: } /*! - * \brief receive + * \brief async_receive * \param message_handler The function to call when a message has been received. */ - void receive(MessageHandler message_handler) { + void async_receive(MessageHandler message_handler) { using namespace boost::asio::placeholders; socket.async_receive( diff --git a/libcmix-network/protobufclient.hpp b/libcmix-network/protobufclient.hpp index 077ce62..c28c347 100644 --- a/libcmix-network/protobufclient.hpp +++ b/libcmix-network/protobufclient.hpp @@ -3,150 +3,43 @@ #include "client.hpp" #include "logging.hpp" -#include "cmix.pb.h" #include -struct Send; -struct Receive; -struct SendReceive; - -template -class ProtobufClient; - -typedef ProtobufClient Receiver; -typedef ProtobufClient Sender; -typedef ProtobufClient SenderReceiver; - -template -class ProtobufClient +template +class ProtobufClient : private Client { - Client client; - - - #define MESSAGE_SETTER(TYPE, NAME) \ - void message_setter(cmix_proto::CMixMessage& m, cmix_proto::TYPE const& v) { \ - *m.mutable_##NAME() = v; \ - } \ - - MESSAGE_SETTER(Initialization, initialization) - MESSAGE_SETTER(ImANode, imanode) - MESSAGE_SETTER(ImAClient, imaclient) - MESSAGE_SETTER(Bye, bye) - MESSAGE_SETTER(KeyExchange, keyexchange) - - #undef MESSAGE_SETTER - public: - /*! - * \brief ProtobufClient - * \param socket An rvalue reference to a socket it will now own and receive from. - */ - ProtobufClient(boost::asio::ip::tcp::socket&& socket) - : client(std::move(socket)) - {} - - /*! - * \brief Move constructor for ProtobufClient. - */ - ProtobufClient(ProtobufClient&& c) = default; - - ProtobufClient(Client&& c) - : client(std::move(c)) - {} - - template - ProtobufClient(ProtobufClient&& r) - : client(std::move(r.client)) - {} - - /*! - * \brief Move assignment for ProtobufClient. - */ - ProtobufClient& operator=(ProtobufClient&&) = default; - - /*! - * \brief async_connect Asynchronously connects to next_host:port and calls on_connect - * \param next_host The host to connect to - * \param next_port The port to connect to - * \param on_connect The callback to call on a succes. - */ - template - void async_connect(std::string next_host, std::string next_port, F on_connect) { - client.async_connect(next_host, next_port, on_connect); - } + using Client::Client; + using Client::operator=; + using Client::async_connect; - template::value || std::is_same::value), void>::type* = nullptr> + template void async_send(V value, F on_sent) { - cmix_proto::CMixMessage m; - message_setter(m, value); - client.async_send(m.SerializeAsString(), on_sent); + typename T::proto_type m = T()(value); + Client::async_send(m.SerializeAsString(), on_sent); } - /*! - * \brief send sends the string prefixed with it's length over the socket asynchronously. - * \param message The string to be sent. - */ - template::value || std::is_same::value)>::type* = nullptr> + template void async_send(V value) { - cmix_proto::CMixMessage m; - message_setter(m, value); - client.async_send(m.SerializeAsString(), []{}); + async_send(value, []{}); } - /*! - * \brief receive - * \param message_handler The function to call when a message has been received. - */ - template ::value || std::is_same::value)>::type* = nullptr> - void receive(F message_handler) { + template + void async_receive(F message_handler) { auto f = [message_handler](std::vector const& buffer) { - cmix_proto::CMixMessage message; + typename T::proto_type message; if(!message.ParseFromArray(buffer.data(), buffer.size())) { BOOST_LOG_TRIVIAL(error) << "Received something which was not a CMixMessage"; throw std::runtime_error("Network communication was disrupted in a unrecoverable way."); } message_handler(message); }; - client.receive(f); - } - - /*! - * \brief close Closes the underlying socket. - */ - void close(){ - client.close(); + Client::async_receive(f); } - /*! - * \brief on_done sets the done callback. - * \param f The new done callback function. - */ - template - void on_done(F f) { - client.on_done(f); - } - - bool is_open() const{ - return client.is_open(); - } - - friend Receiver make_receiver(Receiver&& r); - - friend SenderReceiver make_sender_receiver(SenderReceiver&& r); - friend SenderReceiver make_sender_receiver(Receiver&& r); + using Client::close; + using Client::on_done; + using Client::is_open; }; - -inline Receiver make_receiver(Receiver&& r) { - return Receiver(std::move(r.client)); -} - -inline SenderReceiver make_sender_receiver(SenderReceiver&& r) { - return SenderReceiver(std::move(r.client)); -} - -inline SenderReceiver make_sender_receiver(Receiver&& r) -{ - return SenderReceiver(std::move(r.client)); -} -- cgit v1.2.3-70-g09d2