## Prerequisites

This tutorial builds on the [domain objects](https://fuchsia.dev/docs/development/languages/fidl/tutorials/cpp/basics/domain-objects) tutorial. For the
full set of FIDL tutorials, refer to the [overview](https://fuchsia.dev/docs/development/languages/fidl/tutorials/overview).

## Overview

This tutorial shows you how to implement a server for a FIDL protocol
(`fuchsia.examples/Echo`) and run it on Fuchsia. This protocol has one method
of each kind: a one-way method, a two-way method, and an event:

    @discoverable
    closed protocol Echo {
        strict EchoString(struct {
            value string:MAX_STRING_LENGTH;
        }) -> (struct {
            response string:MAX_STRING_LENGTH;
        });
        strict SendString(struct {
            value string:MAX_STRING_LENGTH;
        });
        strict -> OnString(struct {
            response string:MAX_STRING_LENGTH;
        });
    };

For more on FIDL methods and messaging models, refer to the
[FIDL concepts](https://fuchsia.dev/docs/concepts/fidl/overview) page.

This document covers how to complete the following tasks:

- [Implement the FIDL protocol](https://fuchsia.dev/fuchsia-src/development/languages/fidl/tutorials/cpp/basics/server.md.txt#protocol).
- [Publish the protocol implementation](https://fuchsia.dev/fuchsia-src/development/languages/fidl/tutorials/cpp/basics/server.md.txt#serve).
- [Run the server](https://fuchsia.dev/fuchsia-src/development/languages/fidl/tutorials/cpp/basics/server.md.txt#run).

## Structure of the server example

The example code accompanying this tutorial is located in your Fuchsia checkout
at [`//examples/fidl/cpp/server`](https://cs.opensource.google/fuchsia/fuchsia/+/main:/examples/fidl/cpp/server). It consists of a server
component and its containing package. For more information about building
components, see [Build components](https://fuchsia.dev/docs/development/components/build).

To get the server component up and running, there are three targets that are
defined in `//examples/fidl/cpp/server/BUILD.bazel`:

1. The raw executable file for the server. This produces a binary with the
   specified output name that can run on Fuchsia:

   ```python
   fx_cc_binary(
       name = "bin",
       srcs = ["main.cc"],
       gn_output_name = "fidl_echo_cpp_server",
       tags = ["manual"],
       deps = [
           "//examples/fidl/fuchsia.examples:fuchsia.examples_cpp",

           # This library provides an asynchronous event loop implementation.
           "//sdk/lib/async-loop:async-loop-cpp",

           # This library is used to publish capabilities, e.g. protocols,
           # to the component's outgoing directory.
           "//sdk/lib/component/outgoing/cpp",

           # This library is used to log messages.
           "//sdk/lib/syslog/cpp",
       ],
   )

   ```
2. A component that is set up to run the server executable.
   Components are the units of software execution on Fuchsia. A component is
   described by its manifest file. In this case `meta/server.cml`
   configures `echo-server` as an executable component which runs
   `fidl_echo_cpp_server` in `:bin`.

   ```python
   fx_component_manifest(
       name = "echo-server_manifest",
       component_name = "echo_server",
       includes = ["//sdk/lib/syslog:client.shard"],
       manifest = "meta/server.cml",
   )

   fx_component(
       name = "echo-server",
       compiled_manifest = ":echo-server_manifest",
       visibility = [
           "//examples/fidl:__subpackages__",
           "//sdk/ctf/tests/examples/fidl/fuchsia.examples/testing/realm-factory:__pkg__",
       ],
       deps = [":bin_packaged"],
   )

   ```

   The server component manifest is located at
   `//examples/fidl/cpp/server/meta/server.cml`. The binary name in the
   manifest must match the output name of the `executable` defined in
   `BUILD.bazel`.

   ```json5
   {
       include: [ "syslog/client.shard.cml" ],

       // Information about the program to run.
       program: {
           // Use the built-in ELF runner.
           runner: "elf",

           // The binary to run for this component.
           binary: "bin/fidl_echo_cpp_server",
       },

       // Capabilities provided by this component.
       capabilities: [
           { protocol: "fuchsia.examples.Echo" },
       ],
       expose: [
           {
               protocol: "fuchsia.examples.Echo",
               from: "self",
           },
       ],
   }

   ```
3. The component is then put into a package, which is the unit of software
   distribution on Fuchsia. In this case, the package just contains a
   single component.

   ```python
   # @bazel2gn:skip
   fx_package(
       name = "echo-cpp-server",
       components = [":echo-server"],
       visibility = ["//examples/fidl/cpp:__pkg__"],
   )
   ```

### Building the server

You may build the server package via the following:

1. Add the server to your build configuration. This only needs to be done once:

   ```bash
   fx set core.x64 --with //examples/fidl/cpp/server
   ```
2. Build the server package:

   ```bash
   fx build //examples/fidl/cpp/server
   ```

> [!NOTE]
> **Note:** This build configuration assumes your device target is the emulator. To run the example on a physical device, select the appropriate [product configuration](https://fuchsia.dev/docs/development/build/software_assembly/build_configuration) for your hardware.

## Implement the FIDL protocol

`EchoImpl` implements the server request handler for the `fuchsia.examples/Echo`
protocol. To do so, `EchoImpl` inherits from the generated pure virtual server
interface `fidl::Server<fuchsia_examples::Echo>`, and overrides its pure virtual
methods corresponding to every one way and two way call:

```c++
class EchoImpl : public fidl::Server<fuchsia_examples::Echo> {
 public:
  // The handler for `fuchsia.examples/Echo.EchoString`.
  //
  // For two-way methods (those with a response) like this one, the completer is
  // used complete the call: either to send the reply via |completer.Reply|, or
  // close the channel via |completer.Close|.
  //
  // |EchoStringRequest| exposes the same API as the request struct domain
  // object, that is |fuchsia_examples::EchoEchoStringRequest|.
  void EchoString(EchoStringRequest& request, EchoStringCompleter::Sync& completer) override {
    // Call |Reply| to reply synchronously with the request value.
    completer.Reply({{.response = request.value()}});
  }

  // The handler for `fuchsia.examples/Echo.SendString`.
  //
  // For fire-and-forget methods like this one, the completer is normally not
  // used, but its |Close(zx_status_t)| method can be used to close the channel,
  // either when the protocol has reached its intended terminal state or the
  // server encountered an unrecoverable error.
  //
  // |SendStringRequest| exposes the same API as the request struct domain
  // object, that is |fuchsia_examples::EchoSendStringRequest|.
  void SendString(SendStringRequest& request, SendStringCompleter::Sync& completer) override {
    ZX_ASSERT(binding_ref_.has_value());

    // Handle a SendString request by sending an |OnString| event (an
    // unsolicited server-to-client message) back to the client.
    fit::result result = fidl::SendEvent(*binding_ref_)->OnString({request.value()});
    if (!result.is_ok()) {
      FX_LOGS(ERROR) << "Error sending event: " << result.error_value();
    }
  }

  // ... other methods from examples/fidl/cpp/server/main.cc omitted, to be covered later.

 private:
  // `ServerBindingRef` can be used to:
  // - Control the binding, such as to unbind the server from the channel or
  //   close the channel.
  // - Send events back to the client.
  // See the documentation comments on |fidl::ServerBindingRef|.
  std::optional<fidl::ServerBindingRef<fuchsia_examples::Echo>> binding_ref_;
};
```

> [!NOTE]
> **Note:** in this tutorial the `EchoString` handler replies synchronously. For asynchronous replies, see [responding to requests asynchronously](https://fuchsia.dev/docs/development/languages/fidl/tutorials/cpp/topics/async-completer).

### Bind the implementation to a server endpoint

Implementing the request handlers is only half the story. The server needs to be
able to monitor new messages that arrives on a
[server endpoint](https://fuchsia.dev/docs/reference/fidl/language/language#protocols-use). To do this, `EchoImpl` defines two more
methods: a `BindSelfManagedServer` static factory function that creates a
new `EchoImpl` instance to handle requests on a new server endpoint
`fidl::ServerEnd<fuchsia_examples::Echo>`, and an `OnUnbound` method that
is called when the connection is torn down:

```c++
/* Inside `class EchoImpl {`... */

  // Bind a new implementation of |EchoImpl| to handle requests coming from
  // the server endpoint |server_end|.
  static void BindSelfManagedServer(async_dispatcher_t* dispatcher,
                                    fidl::ServerEnd<fuchsia_examples::Echo> server_end) {
    // Create a new instance of |EchoImpl|.
    std::unique_ptr impl = std::make_unique<EchoImpl>();
    EchoImpl* impl_ptr = impl.get();

    // |fidl::BindServer| takes a FIDL protocol server implementation and a
    // channel. It asynchronously reads requests off the channel, decodes them
    // and dispatches them to the correct handler on the server implementation.
    //
    // The FIDL protocol server implementation can be passed as a
    // |std::shared_ptr|, |std::unique_ptr|, or raw pointer. For shared and
    // unique pointers, the binding will manage the lifetime of the
    // implementation object. For raw pointers, it's up to the caller to ensure
    // that the implementation object outlives the binding but does not leak.
    //
    // See the documentation comment of |fidl::BindServer|.
    fidl::ServerBindingRef binding_ref = fidl::BindServer(
        dispatcher, std::move(server_end), std::move(impl), std::mem_fn(&EchoImpl::OnUnbound));
    // Put the returned |binding_ref| into the |EchoImpl| object.
    impl_ptr->binding_ref_.emplace(std::move(binding_ref));
  }

  // This method is passed to the |BindServer| call as the last argument,
  // which means it will be called when the connection is torn down.
  // In this example we use it to log some connection lifecycle information.
  // Production code could do more things such as resource cleanup.
  void OnUnbound(fidl::UnbindInfo info, fidl::ServerEnd<fuchsia_examples::Echo> server_end) {
    // |is_user_initiated| returns true if the server code called |Close| on a
    // completer, or |Unbind| / |Close| on the |binding_ref_|, to proactively
    // teardown the connection. These cases are usually part of normal server
    // shutdown, so logging is unnecessary.
    if (info.is_user_initiated()) {
      return;
    }
    if (info.is_peer_closed()) {
      // If the peer (the client) closed their endpoint, log that as INFO.
      FX_LOGS(INFO) << "Client disconnected";
    } else {
      // Treat other unbind causes as errors.
      FX_LOGS(ERROR) << "Server error: " << info;
    }
  }
```

## Publish the protocol implementation

A component that implements a FIDL protocol can expose that FIDL
protocol to other components. This is done by publishing the protocol
implementation to the component's


[](https://fuchsia.dev/docs/glossary#outgoing-directory)


. This complete process is
described in further detail in the [Life of a protocol open](https://fuchsia.dev/docs/concepts/components/v2/capabilities/life_of_a_protocol_open#binding_to_a_component_and_sending_a_protocol_channel).
We can use `component::OutgoingDirectory` from the C++ component runtime library
to perform the heavy lifting.

To depend on the component runtime library:

```python
fx_cc_binary(
    name = "bin",
    srcs = ["main.cc"],
    gn_output_name = "fidl_echo_cpp_server",
    tags = ["manual"],
    deps = [
        "//examples/fidl/fuchsia.examples:fuchsia.examples_cpp",

        # This library provides an asynchronous event loop implementation.
        "//sdk/lib/async-loop:async-loop-cpp",

# This library is used to publish capabilities, e.g. protocols,
        # to the component's outgoing directory.
        "//sdk/lib/component/outgoing/cpp",

        # This library is used to log messages.
        "//sdk/lib/syslog/cpp",
    ],
)
```

Import the library at the top of `examples/fidl/cpp/server/main.cc`:

```c++
#include <fidl/fuchsia.examples/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include \<lib/component/outgoing/cpp/outgoing_directory.h\>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>
```

Serve the component's outgoing directory:

```c++
int main(int argc, const char** argv) {
  // The event loop is used to asynchronously listen for incoming connections
  // and requests from the client. The following initializes the loop, and
  // obtains the dispatcher, which will be used when binding the server
  // implementation to a channel.
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  fuchsia_logging::LogSettingsBuilder builder;
  builder.WithDispatcher(dispatcher).BuildAndInitialize();

  // Create an |OutgoingDirectory| instance.
  //
  // The |component::OutgoingDirectory| class serves the outgoing directory for
  // our component. This directory is where the outgoing FIDL protocols are
  // installed so that they can be provided to other components.
  component::OutgoingDirectory outgoing = component::OutgoingDirectory(dispatcher);

  // The `ServeFromStartupInfo()` function sets up the outgoing directory with
  // the startup handle. The startup handle is a handle provided to every
  // component by the system, so that they can serve capabilities (e.g. FIDL
  // protocols) to other components.
  zx::result result = outgoing.ServeFromStartupInfo();
  if (result.is_error()) {
    FX_LOGS(ERROR) << "Failed to serve outgoing directory: " << result.status_string();
    return -1;
  }

  // ...
```

### Serve the protocol

The server then registers the Echo protocol using `outgoing.AddProtocol`.

```c++
int main(int argc, const char** argv) {
  // The event loop is used to asynchronously listen for incoming connections
  // and requests from the client. The following initializes the loop, and
  // obtains the dispatcher, which will be used when binding the server
  // implementation to a channel.
  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  async_dispatcher_t* dispatcher = loop.dispatcher();
  fuchsia_logging::LogSettingsBuilder builder;
  builder.WithDispatcher(dispatcher).BuildAndInitialize();

  // Create an |OutgoingDirectory| instance.
  //
  // The |component::OutgoingDirectory| class serves the outgoing directory for
  // our component. This directory is where the outgoing FIDL protocols are
  // installed so that they can be provided to other components.
  component::OutgoingDirectory outgoing = component::OutgoingDirectory(dispatcher);

  // The `ServeFromStartupInfo()` function sets up the outgoing directory with
  // the startup handle. The startup handle is a handle provided to every
  // component by the system, so that they can serve capabilities (e.g. FIDL
  // protocols) to other components.
  zx::result result = outgoing.ServeFromStartupInfo();
  if (result.is_error()) {
    FX_LOGS(ERROR) << "Failed to serve outgoing directory: " << result.status_string();
    return -1;
  }

// Register a handler for components trying to connect to fuchsia.examples.Echo.
result = outgoing.AddUnmanagedProtocol\<fuchsia_examples::Echo\>(
\[dispatcher\](fidl::ServerEnd\<fuchsia_examples::Echo\> server_end) {
FX_LOGS(INFO) \<\< "Incoming connection for "
\<\< fidl::DiscoverableProtocolName\<fuchsia_examples::Echo\>;
EchoImpl::BindSelfManagedServer(dispatcher, std::move(server_end));
});
if (result.is_error()) {
FX_LOGS(ERROR) \<\< "Failed to add Echo protocol: " \<\< result.status_string();
    return -1;
  }

  FX_LOGS(INFO) << "Running C++ echo server with natural types";

  // This runs the event loop and blocks until the loop is quit or shutdown.
  // See documentation comments on |async::Loop|.
  loop.Run();
  return 0;
}
```

The call to `AddProtocol` installs a handler at the name of the FIDL protocol
(`fidl::DiscoverableProtocolName<fuchsia_examples::Echo>`, which is the string
`"fuchsia.examples.Echo"`). When a client component connects to
`fuchsia.examples.Echo`, `outgoing` will call the lambda function that we
created with a server endpoint corresponding to the client endpoint from the
client, and this lambda function will call the `EchoImpl::BindSelfManagedServer`
detailed above to bind the server endpoint to a new instance of `EchoImpl`.

Our main method will keep listening for incoming requests on the
[async loop](https://cs.opensource.google/fuchsia/fuchsia/+/main:/sdk/lib/async-loop/include/lib/async-loop/cpp/loop.h).

## Test the server

After [building the server](https://fuchsia.dev/fuchsia-src/development/languages/fidl/tutorials/cpp/basics/server.md.txt#build), you may run the example on a running
instance of Fuchsia emulator via

```bash
ffx component run /core/ffx-laboratory:echo-server fuchsia-pkg://fuchsia.com/echo-cpp-server#meta/echo_server.cm
```

> [!NOTE]
> **Note:** Components are resolved using their [](https://fuchsia.dev/docs/glossary#component-url) , which is determined with the [](https://fuchsia.dev/docs/glossary#fuchsia-pkg-url) scheme.

You should see output similar to the following in the device logs (`ffx log`):

    [ffx-laboratory:echo_server][][I] Running C++ echo server with natural types

The server is now running and waiting for incoming requests.
The next step will be to write a client that sends `Echo` protocol requests.
For now, you can simply terminate the server component:

```bash
ffx component destroy /core/ffx-laboratory:echo_server
```

> [!NOTE]
> **Note:** Component instances are referenced by their [](https://fuchsia.dev/docs/glossary#moniker) , which is determined by their location in the [](https://fuchsia.dev/docs/glossary#component-instance-tree)

## Serve requests using wire domain objects

The above tutorial implements a server with
[natural domain objects](https://fuchsia.dev/docs/development/languages/fidl/tutorials/cpp/basics/domain-objects#using-natural): the server receives requests
represented in natural domain objects, and sends replies encoded from natural
domain objects. When optimizing for performance and heap allocation, one may
implement a server that speaks [wire domain objects](https://fuchsia.dev/docs/development/languages/fidl/tutorials/cpp/basics/domain-objects#using-wire), i.e. a wire
server. Here is the `EchoImpl` rewritten to use wire domain objects:

```c++
class EchoImpl final : public fidl::WireServer<fuchsia_examples::Echo> {
 public:
  // The handler for `fuchsia.examples/Echo.EchoString`.
  //
  // For two-way methods (those with a response) like this one, the completer is
  // used complete the call: either to send the reply via |completer.Reply|, or
  // close the channel via |completer.Close|.
  //
  // |EchoStringRequestView| exposes the same API as a pointer to the request
  // struct domain object, that is
  // |fuchsia_examples::wire::EchoEchoStringRequest*|.
  void EchoString(EchoStringRequestView request, EchoStringCompleter::Sync& completer) override {
    // Call |Reply| to reply synchronously with the request value.
    completer.Reply(request->value);
  }

  // The handler for `fuchsia.examples/Echo.SendString`.
  //
  // For fire-and-forget methods like this one, the completer is normally not
  // used, but its |Close(zx_status_t)| method can be used to close the channel,
  // either when the protocol has reached its intended terminal state or the
  // server encountered an unrecoverable error.
  //
  // |SendStringRequestView| exposes the same API as a pointer to the request
  // struct domain object, that is
  // |fuchsia_examples::wire::EchoSendStringRequest*|.
  void SendString(SendStringRequestView request, SendStringCompleter::Sync& completer) override {
    // Handle a SendString request by sending an |OnString| event (an
    // unsolicited server-to-client message) back to the client.
    fidl::Status status = fidl::WireSendEvent(binding_)->OnString(request->value);
    if (!status.ok()) {
      FX_LOGS(ERROR) << "Error sending event: " << status.error();
    }
  }

  // ... |BindSelfManagedServer| etc omitted. Those stay the same.
};
```

The relevant classes and functions used in a wire server have similar shapes to
those used in a natural server. When a different class or function is called
for, the wire counterpart is usually prefixed with `Wire`. There are also
small differences in pointers vs references and argument structure:

- The server interface implemented by a natural server is
  `fidl::Server<fuchsia_examples::Echo>`. The server interface implemented by a
  wire server is `fidl::WireServer<fuchsia_examples::Echo>`.

- The handler function in a natural server takes a reference to the request
  message. The `Reply` method takes a single argument that is the response
  payload domain object:

  ```c++
  void EchoString(EchoStringRequest& request, EchoStringCompleter::Sync& completer) override {
    // Call |Reply| to reply synchronously with the request value.
    completer.Reply({{.response = request.value()}});
  }
  ```

  Whereas the handler function in a wire server takes a view (akin to a pointer)
  of the request message. When the response payload is a struct, the `Reply`
  method flattens the list of struct fields in the response payload into
  separate arguments (here, a single `fidl::StringView` argument):

  ```c++
  void EchoString(EchoStringRequestView request, EchoStringCompleter::Sync& completer) override {
    // Call |Reply| to reply synchronously with the request value.
    completer.Reply(request->value);
  }
  ```
- The function to send events with natural types is `fidl::SendEvent`. The
  function to send events with wire types is `fidl::WireSendEvent`. Struct
  fields are also flattened into separate arguments when sending an event.

The same `fidl::BindServer` function may be used to bind either a natural server
or a wire server.

The full example code for a wire server is located in your Fuchsia checkout
at [`//examples/fidl/cpp/server/wire`](https://cs.opensource.google/fuchsia/fuchsia/+/main:/examples/fidl/cpp/server/wire).
[](https://issues.fuchsia.dev/issues/new?component=1439230&template=1881640&description=Issue+on:+https://fuchsia.dev/docs/development/languages/fidl/tutorials/cpp/basics/server.md "Report a bug or suggest improvements on this page") [](https://cs.opensource.google/fuchsia/fuchsia/+/main:docs/development/languages/fidl/tutorials/cpp/basics/server.md "View the source code of this page") [](https://ci.android.com/edit?repo=fuchsia/fuchsia/main&file=docs/development/languages/fidl/tutorials/cpp/basics/server.md&cloneRepo=fuchsia/fuchsia:refs/heads/main&fullPath=fuchsia/docs/development/languages/fidl/tutorials/cpp/basics/server.md "Edit the source code of this page")