Example Echo Client & Server
====

This echo client/server demonstrate how to create and use a mojom interface,
as well as demonstrating one way to communicate between mojo applications.

For a deeper dive into this code, refer to the [Mojo
Tutorial](https://docs.google.com/document/d/1mufrtxTk8w9qa3jcnlgqsYkWlyhwEpc7aWNaSOks7ug).

## Running the Echo Client & Server

```
$ ./mojo/tools/mojob.py gn
$ ./mojo/tools/mojob.py build
$ ./out/Debug/mojo_shell mojo:echo_client
```
You should see output along the lines of:

```
[1010/194919:INFO:echo_client.cc(21)] ***** Response: hello world
```

This means that our echo_client started, contacted the echo_server (which was
started by the shell), sent a string through a mojom interface, and got a
response.

## Echo Client Structure

By running the echo_client through mojo_shell, we run a [Mojo
Application](https://docs.google.com/document/d/1xjt_TPjTu0elix8fNdBgWmnjJdJAtqSr1XDS_C-Ct8E).
Mojo Applications have main threads (run as `MojoMain`), and they may
communicate with other applications using Mojo IPC. This section will describe
the steps taken to start up the echo client, and what is necessary
to make an IPC call to the echo server service.

### ApplicationRunner: It calls your application

In echo_client.cc's MojoMain function, a new `ApplicationRunner` called `runner`
is created. This class is used by the shell for setting up and communicating
with an application. This is a common pattern in Mojo apps: a runner takes an
implementation of an `ApplicationDelegate` and runs it.

In echo_client, the delegate is a class called `EchoClientDelegate`.

### ApplicationDelegate: Your application will be a subclass of this

The ApplicationDelegate class is what we can think of as the heart of our
"app". It can implement three methods:

1. `void Initialize(ApplicationImpl* app)` -- Called during setup.
2. `bool ConfigureIncomingConnection(ApplicationConnection* connection)` --
   Configures what happens when a connection attempts to reach our application.
3. `void Quit()` -- Called before termination.

Our echo_client only implements the `Initialize` method, since it does not need
to accept any incoming connections (it just makes one outgoing connection).

This initialize method takes an `ApplicationImpl* app` as an argument, which can
be used to contact other services. Here, we contact the "mojo:echo_server"
service using the `ConnectToService` method. This method takes a URL as an
argument, and passes an interface back in an `InterfacePtr`.

```
app->ConnectToService("mojo:echo_server", &echo_);
```

Note: When the Mojo Shell notices the echo_server service is not running, it
will automatically start the server service. This is why only running the client
is necessary for this example to work.

### Mojom Interfaces: An mechanism for predictable message passing

Interfaces are defined in ".mojom" files, and they allow applications to
interact with each other in a procedure-call mechanism. In mojom interfaces,
a client invokes a method, the arguments are serialized and passed to the
receiver, and the receiver invokes the method (and returns any results).

The [Mojom
language](https://docs.google.com/document/d/1r7yCseBktlDEN9CKp_JWD0ZYxMi4GCsLXMvSN5sI04k)
is used to define the simple `EchoString` interface, defined in echo.mojom.  To
compile the mojom interface, it must be built using the "mojom" template in a
BUILD.gn file. The "echo.mojom" file is compiled as a part of a target named
"bindings". This will autogenerate a few files, one of which we are including in
our echo_client.cc example: "examples/echo/echo.mojom.h". Since our mojom file
specifies `interface Echo`, we can refer to the `EchoPtr` type to access our
interface.

If you create an `interface FooBar`, then you can use a type `FooBarPtr` to
reference your interface.

Since our interface defines the method:

```
EchoString(string? value) => (string? value)
```

this creates the following method (and more code, not shown):

```
void EchoString(const mojo::String& value, mojo::Callback<void(mojo::String)>);
```

This method is callable on an `InterfacePtr` which properly implements our mojom
interface (so, in this case, an `EchoPtr`, like the one returned from our
call to `ConnectToService`).

The second argument to our interface is a `mojo::Callback` class, which is
just a Runnable with varying arguments.  For the echo_client example, we created
a `ResponsePrinter` class to act as this callback. By implementing `Run`, which
merely prints out the string we get from the echo server, we are able to call
the `EchoString` method on the `EchoPtr` received from `ConnectToService`.

```
echo_->EchoString("hello world", ResponsePrinter());
```

In summary, the echo_client connects to the echo_server service using
the `ConnectToService` method, passing an interface defined in a mojom file. The
methods of this interface can then be invoked on the `EchoPtr`, with appropriate
callback implementations being passed where necessary.

## Echo Server Structure

The echo server, like the echo client, is implemented as an application. This
means it has a `MojoMain` function, an `ApplicationRunner`, and an
`ApplicationDelegate` actually implementing the core application.

echo_server.cc contains three different types of servers, though only one can be
used at a time. To try changing the server, uncomment one of the lines in
MojoMain. These different `ApplicationDelegate` derivations demonstrate how
differently the `InterfaceFactory` can be created.  Each server derives from
`InterfaceFactory`, which implements an interface and binds it to incoming
requests.

All three servers, being `ApplicationDelegate` derivations, implement
`ConfigureIncomingConnection` in the same way:

```
connection->AddService<Echo>(this);
```

This should be read as "For any incoming connections to this server, use `this`
as a factory to create the Echo interface".

Each server's `Create` method will now be called when a new connection wants
to access the Echo interface.

### EchoImpl: The Interface Implementation

All three implementations use the `EchoImpl` class, implementing the `Echo`
interface we defined in our mojom file, which does what you would expect of an
echo server: it sends back the supplied value String back to the client.

```
callback.Run(value);
```

If we wanted the server to pass back something else, we would pass a different
value here. However, as defined by our interface, the echo server can only
return a String.

### Server 1: MultiServer

On calls to `Create`, this server creates a new `StrongBindingEchoImpl` object
for each request.  This object is derived from `EchoImpl`, so it implements the
interface, but by using the `StrongBinding` class, it cleans up after itself
once the message pipe used for the request is closed.

### Server 2: SingletonServer

This server creates an `EchoImpl` object when it is constructed, and for each
call to `Create`, binds the request to this single implementation. A
`BindingSet` is used so that multiple requests can be bound to the same object.

### Server 3: OneAtATimeServer

This server creates an `EchoImpl` object, like the `SingletonServer`, but uses a
single `Binding`, rather than a `BindingSet`. This means that when a new client
connects to the OneAtATimeServer, the previous binding is closed, and a new
binding is made between the new client and the interface implementation.

The OneAtATimeServer demonstrates a pattern that should be avoided because it
contains a race condition for multiple clients.  If a new client binds to the
server before the first client managed to call EchoString, the first client's
call would cause an error. Unless you have a specific use case for this
behavior, it is advised to avoid creating a server like this.
