#pragma once #ifndef SERVER_H_S0HB5KXY #define SERVER_H_S0HB5KXY #include "rpc/config.h" #include "rpc/msgpack.hpp" #include "rpc/dispatcher.h" #include "rpc/detail/pimpl.h" namespace rpc { namespace detail { class server_session; } //! \brief Implements a msgpack-rpc server. This is the main interfacing //! point with the library for creating servers. //! //! The server maintains a registry of function bindings that it uses to //! dispatch calls. It also takes care of managing worker threads and TCP //! connections. //! The server does not start listening right after construction in order //! to allow binding functions before that. Use the `run` or `async_run` //! functions to start listening on the port. class server { public: //! \brief Constructs a server that listens on the localhost on the //! specified port. //! //! \param port The port number to listen on. explicit server(uint16_t port); //! \brief Constructs a server that listens on the specified address on //! the specified port. //! //! \param port The port number to listen on. server(std::string const &address, uint16_t port); //! \brief Destructor. //! //! When the server is destroyed, all ongoin sessions are closed gracefully. ~server(); //! \brief Starts the server loop. This is a blocking call. //! //! First and foremost, running the event loop causes the server to start //! listening on the specified port. Also, as connections are established //! and calls are made by clients, the server executes the calls as part //! of this call. This means that the handlers are executed on the thread //! that calls `run`. Reads and writes are initiated by this function //% internally as well. void run(); //! \brief Starts the server loop on one or more threads. This is a //! non-blocking call. //! //! This function behaves similarly to `run`, except the event loop is //! optionally started on different threads. Effectively this sets up a //! worker thread pool for the server. Handlers will be executed on one //! of the threads. //! //! \param worker_threads The number of worker threads to start. void async_run(std::size_t worker_threads = 1); //! \brief Binds a functor to a name so it becomes callable via RPC. //! //! This function template accepts a wide range of callables. The arguments //! and return types of these callables should be serializable by msgpack. //! `bind` effectively generates a suitable, light-weight compile-time //! wrapper for the functor. //! //! \param name The name of the functor. //! \param func The functor to bind. //! \tparam F The type of the functor. template void bind(std::string const &name, F func) { disp_->bind(name, func); } //! \brief Sets the exception behavior in handlers. By default, //! handlers throwing will crash the server. If suppressing is on, //! the server will try to gather textual data and return it to //! the client as an error response. //! \note Setting this flag only affects subsequent connections. void suppress_exceptions(bool suppress); //! \brief Stops the server. //! \note This should not be called from worker threads. void stop(); //! \brief Closes all sessions gracefully. void close_sessions(); friend class detail::server_session; private: RPCLIB_DECLARE_PIMPL() std::shared_ptr disp_; }; } /* rpc */ #endif /* end of include guard: SERVER_H_S0HB5KXY */