1 #pragma once 2 3 #ifndef SERVER_H_S0HB5KXY 4 #define SERVER_H_S0HB5KXY 5 6 #include "rpc/config.h" 7 #include "rpc/msgpack.hpp" 8 #include "rpc/dispatcher.h" 9 10 #include "rpc/detail/pimpl.h" 11 12 namespace rpc { 13 14 namespace detail { 15 class server_session; 16 } 17 18 //! \brief Implements a msgpack-rpc server. This is the main interfacing 19 //! point with the library for creating servers. 20 //! 21 //! The server maintains a registry of function bindings that it uses to 22 //! dispatch calls. It also takes care of managing worker threads and TCP 23 //! connections. 24 //! The server does not start listening right after construction in order 25 //! to allow binding functions before that. Use the `run` or `async_run` 26 //! functions to start listening on the port. 27 //! This class is not copyable, but moveable. 28 class server { 29 public: 30 //! \brief Constructs a server that listens on the localhost on the 31 //! specified port. 32 //! 33 //! \param port The port number to listen on. 34 explicit server(uint16_t port); 35 36 //! \brief Move constructor. This is implemented by calling the 37 //! move assignment operator. 38 //! 39 //! \param other The other instance to move from. 40 server(server&& other) noexcept; 41 42 //! \brief Constructs a server that listens on the specified address on 43 //! the specified port. 44 //! 45 //! \param address The address to bind to. This only works if oee of your 46 //! network adapaters control the given address. 47 //! \param port The port number to listen on. 48 server(std::string const &address, uint16_t port); 49 50 //! \brief Destructor. 51 //! 52 //! When the server is destroyed, all ongoin sessions are closed gracefully. 53 ~server(); 54 55 //! \brief Move assignment operator. 56 //! 57 //! \param other The other instance to move from. 58 //! \return The result of the assignment. 59 server& operator=(server&& other); 60 61 //! \brief Starts the server loop. This is a blocking call. 62 //! 63 //! First and foremost, running the event loop causes the server to start 64 //! listening on the specified port. Also, as connections are established 65 //! and calls are made by clients, the server executes the calls as part 66 //! of this call. This means that the handlers are executed on the thread 67 //! that calls `run`. Reads and writes are initiated by this function 68 //! internally as well. 69 void run(); 70 71 //! \brief Starts the server loop on one or more threads. This is a 72 //! non-blocking call. 73 //! 74 //! This function behaves similarly to `run`, except the event loop is 75 //! optionally started on different threads. Effectively this sets up a 76 //! worker thread pool for the server. Handlers will be executed on one 77 //! of the threads. 78 //! 79 //! \param worker_threads The number of worker threads to start. 80 void async_run(std::size_t worker_threads = 1); 81 82 //! \brief Binds a functor to a name so it becomes callable via RPC. 83 //! 84 //! This function template accepts a wide range of callables. The arguments 85 //! and return types of these callables should be serializable by msgpack. 86 //! `bind` effectively generates a suitable, light-weight compile-time 87 //! wrapper for the functor. 88 //! 89 //! \param name The name of the functor. 90 //! \param func The functor to bind. 91 //! \tparam F The type of the functor. bind(std::string const & name,F func)92 template <typename F> void bind(std::string const &name, F func) { 93 disp_->bind(name, func); 94 } 95 96 //! \brief Sets the exception behavior in handlers. By default, 97 //! handlers throwing will crash the server. If suppressing is on, 98 //! the server will try to gather textual data and return it to 99 //! the client as an error response. 100 //! \note Setting this flag only affects subsequent connections. 101 void suppress_exceptions(bool suppress); 102 103 //! \brief Stops the server. 104 //! \note This should not be called from worker threads. 105 void stop(); 106 107 //! \brief Closes all sessions gracefully. 108 void close_sessions(); 109 110 friend class detail::server_session; 111 112 private: 113 //! \brief Closes a specific session. 114 void close_session(std::shared_ptr<detail::server_session> const& s); 115 116 private: 117 RPCLIB_DECLARE_PIMPL() 118 std::shared_ptr<detail::dispatcher> disp_; 119 }; 120 121 } /* rpc */ 122 123 #endif /* end of include guard: SERVER_H_S0HB5KXY */ 124