Servers#

Simple Example#

A msgpack_rpc::servers::Server object can be created using msgpack_rpc::servers::ServerBuilder. After creating a client, msgpack_rpc::servers::Server::run_until_signal() function can be used to run the server until SIGINT or SIGTERM is received.

Example of a Simple Server#
#include "msgpack_rpc/servers/server.h"
#include "msgpack_rpc/servers/server_builder.h"

int main() {
    // Create a server.
    msgpack_rpc::servers::Server server =
        msgpack_rpc::servers::ServerBuilder()
            // Register a method.
            // Specify the signature of the method in the template parameter.
            .add_method<int(int, int)>(
                "add", [](int x, int y) { return x + y; })
            // Specify the URI of the server.
            .listen_to("tcp://localhost:7136")
            // build() creates a server and starts processing of the server.
            .build();

    // Run the server until this process receives SIGINT or SIGTERM.
    // When this function returns, the server is automatically stopped.
    server.run_until_signal();

    return 0;
}

More APIs#

An example with more APIs is shown below.

Example to use various APIs of servers#
#include <cstdlib>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <vector>

#include <fmt/ranges.h>
#include <lyra/lyra.hpp>

#include "msgpack_rpc/addresses/uri.h"
#include "msgpack_rpc/config/config_parser.h"
#include "msgpack_rpc/logging/logger.h"
#include "msgpack_rpc/methods/method_exception.h"
#include "msgpack_rpc/servers/server.h"
#include "msgpack_rpc/servers/server_builder.h"

void parse_command_line_arguments(int argc, char** argv,
    std::string& config_file_path, std::string& config_name);

int main(int argc, char** argv) {
    std::string config_file_path;
    std::string config_name;
    parse_command_line_arguments(argc, argv, config_file_path, config_name);

    // Parse configuration.
    msgpack_rpc::config::ConfigParser parser;
    parser.parse(config_file_path);

    // Create a logger from a configuration.
    const std::shared_ptr<msgpack_rpc::logging::Logger> logger =
        msgpack_rpc::logging::Logger::create(
            parser.logging_config(config_name));

    // Create a server.
    msgpack_rpc::servers::Server server =
        // Optionally specify configurations of the server and a logger.
        msgpack_rpc::servers::ServerBuilder(
            parser.server_config(config_name), logger)

            /* ****************************************************************
             * Register methods.
             ******************************************************************/
            // Register a method using a function object.
            // Specify the signature of the method in the template parameter.
            .add_method<int(int, int)>(
                "add", [](int x, int y) { return x + y; })
            // A method without results can be added.
            .add_method<void(std::string)>("print",
                [logger](const std::string& str) {
                    MSGPACK_RPC_INFO(logger, "message: {}", str);
                })
            // Register a method which throws an exception.
            // Exceptions are thrown in clients.
            .add_method<void()>("throw",
                []() -> void {
                    throw std::runtime_error("Example exception.");
                })
            // Register a method which throws an exception with a serializable
            // object. Exceptions are thrown in clients.
            .add_method<void(int)>("throw_int",
                [](int val) -> void {
                    throw msgpack_rpc::methods::MethodException(val);
                })

            /* ****************************************************************
             * Configure URIs of the server.
             ******************************************************************/
            // Specify a URI of the server.
            .listen_to("tcp://localhost:8246")
            // Several URIs can be specified by calling multiple times.
            .listen_to("tcp://localhost:8247")
            // Specify a TCP port.
            .listen_to_tcp("localhost", 8248)  // NOLINT(*-magic-numbers)
            // URIs can be also added in configuration files.

            // build() creates a server and starts processing of the server.
            .build();

    // Get the server URIs.
    const std::vector<msgpack_rpc::addresses::URI> server_uris =
        server.local_endpoint_uris();
    MSGPACK_RPC_INFO(logger, "Server URIs: [{}]", fmt::join(server_uris, ", "));

    // Run the server until this process receives SIGINT or SIGTERM.
    // When this function returns, the server is automatically stopped.
    server.run_until_signal();

    // Server can be stopped using stop function.
    server.stop();

    return 0;
}

APIs of Servers#

class ServerBuilder#

Class of builders of servers.

Public Functions

inline ServerBuilder()#

Constructor.

This overload will use the default configurations for servers and loggers.

inline explicit ServerBuilder(const config::ServerConfig &server_config, const std::shared_ptr<logging::Logger> &logger = logging::Logger::create())#

Constructor.

Parameters:
  • server_config[in] Configuration of the server.

  • logger[in] Logger.

inline explicit ServerBuilder(const std::shared_ptr<logging::Logger> &logger)#

Constructor.

This overload will use the default configurations for servers.

Parameters:

logger[in] Logger.

template<typename Signature, typename Function>
inline ServerBuilder &add_method(messages::MethodName name, Function &&function)#

Add a method implemented by a function object.

Note

The function can throw exceptions using msgpack_rpc::methods::MethodException class to notify errors using any serializable objects.

Template Parameters:
  • Signature – Signature of the method.

  • Function – Type of the function implementing the method.

Parameters:
  • name[in] Name of the method.

  • function[in] Function implementing the method.

Returns:

This.

inline ServerBuilder &add_method(std::unique_ptr<methods::IMethod> method)#

Add a method.

Note

This overload should not be used in most applications.

Parameters:

method[in] Method.

Returns:

This.

inline Server build()#

Build a server.

Returns:

Server.

inline ServerBuilder &listen_to(addresses::URI uri)#

Add a URI to listen to.

Parameters:

uri[in] URI.

Returns:

This.

inline ServerBuilder &listen_to(std::string_view uri)#

Add a URI to listen to.

Parameters:

uri[in] String of a URI.

Returns:

This.

inline ServerBuilder &listen_to_tcp(std::string_view host, std::uint16_t port_number)#

Add a TCP address to listen to.

Parameters:
  • host[in] Host name.

  • port_number[in] Port number.

Returns:

This.

class Server#

Class of servers.

Servers can be created using ServerBuilder.

Public Functions

inline explicit Server(std::unique_ptr<impl::IServerImpl> impl) noexcept#

Constructor.

Warning

Users should create servers using ServerBuilder instead of this constructor.

Parameters:

impl[in] Object of the internal implementation.

inline std::shared_ptr<executors::IExecutor> executor()#

Get the executor.

Note

This function is mainly for testing. So this function may be removed in the future.

Returns:

Executor.

inline std::vector<addresses::URI> local_endpoint_uris()#

Get the URIs of the local endpoints in this server.

Returns:

URIs.

inline void run_until_signal()#

Run processing of this server until SIGINT or SIGTERM is received.

Note

When this function returns, this server is stopped automatically.

inline void stop()#

Stop processing of this server.

Note

Destructing this server without call of this function will automatically stop this server internally.

class MethodException : public std::exception#

Class of exceptions in methods.

Note

Methods can throw this exception to notify errors using any serializable objects.

Public Functions

MethodException(const MethodException&) noexcept#

Copy constructor.

MethodException(MethodException&&) noexcept#

Move constructor.

template<typename T>
inline explicit MethodException(T &&object, std::enable_if_t<!std::is_same_v<std::decay_t<T>, MethodException>, void*> = nullptr)#

Constructor.

Note

The second argument is for SFINAE, so the second argument should be left unspecified.

Template Parameters:

T – Object specifying the error.

Parameters:

object – Object specifying the error.

~MethodException() noexcept override#

Destructor.

const msgpack::object &object() const noexcept#

Get the object in msgpack library.

Returns:

Object in msgpack library.

MethodException &operator=(const MethodException&) noexcept#

Copy assignment operator.

Returns:

This.

MethodException &operator=(MethodException&&) noexcept#

Move assignment operator.

Returns:

This.

const char *what() const noexcept override#

Get the message of this exception.

Returns:

Message.