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