# Handling multiple clients

## Prerequisites

This tutorial builds on the [HLCPP getting started tutorials][overview].

## Overview

This tutorial updates the [Echo client][client-tut] from the getting started
tutorials to make multiple connections to the server, and update the
[Echo server][server-tut] to handle multiple client connections. For running
multiple instances of a server (or multiple FIDL protocols), see the
tutorial on [services][services-tut].

The full example code for this tutorial is located at
[`//examples/fidl/hlcpp/multiple_clients`][src].

## Implement the server

In the [previous implementation][server-tut-impl], the `main()` function initialized
a single `fidl::Binding`, and bound any incoming requests to it:

```cpp
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/hlcpp/server/main.cc" region_tag="main" highlight="5,7,8,9,10,12" %}
```

This means that if a second client tries to connect to the server at the same
time, the second call to `binding.Bind` will overwrite the channel from the
first client. To support multiple clients, keep track of multiple
`fidl::Binding`s (one for each client) using a `fidl::BindingSet`:

```cpp
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/hlcpp/multiple_clients/server/main.cc" region_tag="main" highlight="5,7" %}
```

A binding set also simplifies the code since it no longer
needs to create a custom handler. The binding set has a `GetHandler` method,
which returns a handler that creates a new `Binding` and stores it in a vector.

To use `fidl::BindingSet`, include `lib/fidl/cpp/binding_set.h`.

## Implement the client

In order to manage multiple clients connected to a protocol, the FIDL HLCPP
runtime library provides an anolog to `fidl::BindingSet`: the
`fidl::InterfacePtrSet`. Use the class to write code that makes multiple
connections to the same protocol:

```cpp
{% includecode gerrit_repo="fuchsia/fuchsia" gerrit_path="examples/fidl/hlcpp/multiple_clients/client/main.cc" region_tag="main" %}
```

The code for setting up a proxy and making requests is the same as in the
[client tutorial][client-main] except it uses
an interface pointer set to simplify the process of broadcasting a message
to a set of clients. An added benefit of using `fidl::InterfacePtrSet` and
`fidl::BindingSet` is that any binding or interface pointer that experiences an
error on its channel is automatically removed from the set.

To use `fidl::InterfacePtrSet`, include `lib/fidl/cpp/interface_ptr_set.h`.


## Run the example

In order for the client and server to communicate using the `Echo` protocol,
component framework must route the `fuchsia.examples.Echo` capability from the
server to the client. For this tutorial, a [realm][glossary.realm] component is
provided to declare the appropriate capabilities and routes.

Note: You can explore the full source for the realm component at
[`//examples/fidl/echo-realm`](/examples/fidl/echo-realm)

1. Configure your build to include the provided package that includes the
   echo realm, server, and client:

    ```posix-terminal
    fx set core.x64 --with //examples/fidl/hlcpp:echo-hlcpp-multi-client
    ```

1. Build the Fuchsia image:

   ```posix-terminal
   fx build
   ```

1. Run the `echo_realm` component. This creates the client and server component
   instances and routes the capabilities:

    ```posix-terminal
    ffx component run /core/ffx-laboratory:echo_realm fuchsia-pkg://fuchsia.com/echo-hlcpp-multi-client#meta/echo_realm.cm
    ```

1. Start the `echo_client` instance:

    ```posix-terminal
    ffx component start /core/ffx-laboratory:echo_realm/echo_client
    ```

The server component starts when the client attempts to connect to the `Echo`
protocol. You should see output similar to the following in the device logs
(`ffx log`):

```none {:.devsite-disable-click-to-copy}
[echo_server][][I] Running echo server
[echo_client][][I] Got response Hello echoer 0
```

Terminate the realm component to stop execution and clean up the component
instances:

```posix-terminal
ffx component destroy /core/ffx-laboratory:echo_realm
```

<!-- xrefs -->
[glossary.realm]: /docs/glossary/README.md#realm
[client-tut]: /docs/development/languages/fidl/tutorials/hlcpp/basics/client.md
[client-main]: /docs/development/languages/fidl/tutorials/hlcpp/basics/client.md#main
[server-tut]: /docs/development/languages/fidl/tutorials/hlcpp/basics/server.md
[server-tut-impl]: /docs/development/languages/fidl/tutorials/hlcpp/basics/server.md#impl
[services-tut]: /docs/development/languages/fidl/tutorials/hlcpp/topics/services.md
[src]: /examples/fidl/hlcpp/multiple_clients
[overview]: /docs/development/languages/fidl/tutorials/hlcpp/README.md
