# Client messages

### Overview <a href="#overview" id="overview"></a>

Client messages are a form of [commands](https://app.gitbook.com/@docs-coherence/s/coherence/~/drafts/-Mdq8mK1otqkhY4bQpdr/authority/commands) that are used for client-to-client communication rather than client-to-entity. To achieve this type of communication a special *connection entity* is automatically created by the [replication server](https://app.gitbook.com/@docs-coherence/s/coherence/~/drafts/-Mdq8mK1otqkhY4bQpdr/api-reference/replication-server) for each connected client. Those entities are subject to a different rule set than standard entities. *Connection entities*:

* Can't be created or destroyed by the client - they are always replication server-driven
* Are global - they are replicated across clients regardless of the in-simulation distance or [live query](https://app.gitbook.com/@docs-coherence/s/coherence/~/drafts/-Mdq8mK1otqkhY4bQpdr/api-reference/network-sdk/livequery) radius

Client messages shine whenever there's a need to communicate something to all the connected players. Usage examples:

* Global chat
* Game state changes: game started, game ended, map changed
* Server announcements
* Server-wide leaderboard
* Server-wide events

### Enabling client messages <a href="#enabling-client-messages" id="enabling-client-messages"></a>

The globality of client messages doesn't fit all game types - for example, it rarely makes sense to keep every client informed about the presence of all players on the server in an MMORPG (think World Of Warcraft). Due to this reason, client messages are **turned off** by default. To enable client messages:

#### 1. Turn on the *global query* in the [Coherence MonoBridge](https://app.gitbook.com/@docs-coherence/s/coherence/~/drafts/-Mdq8mK1otqkhY4bQpdr/api-reference/network-sdk/monobridge) (the `Global Query On` toggle) <a href="#id-1-turn-on-the-global-query-in-the-coherence-monobridge-the-global-query-on-toggle" id="id-1-turn-on-the-global-query-in-the-coherence-monobridge-the-global-query-on-toggle"></a>

![MonoBridge component](https://2821114902-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv0ksjqOy2jWVMwsg4f9k%2Fuploads%2FhXH1zFuAN02IsIDinh88%2Fimage.png?alt=media\&token=891013aa-0537-49b1-be33-5277726d8fc4)

*Global query* enables querying for entities containing a *global component*, including a *connection entity*.

{% hint style="info" %}
Disabling *global query* on one client doesn't affect other clients, i.e. *connection entity* of this client will still be visible to other clients that have the *global query* turned on.
{% endhint %}

#### 2. Create a class that inherits from the `CoherenceClientConnection` class <a href="#id-3-create-a-client-connection-prefab" id="id-3-create-a-client-connection-prefab"></a>

Under the hood, client messages are nothing but [commands](https://app.gitbook.com/@docs-coherence/s/coherence/~/drafts/-Mdq8mK1otqkhY4bQpdr/authority/commands) sent between the *connected entities*. Each such entity is represented on the client side by an instance of a `CoherenceClientConnection` class. Implementing client messages is as simple as adding a new command to our custom connection class:

```csharp
public class PlayerConnection : CoherenceClientConnection
{
    // My chat command
    public void OnChatMessage(string message)
    {
        Debug.Log($"Received chat message: {message}");
    }
}
```

#### 3. Create a client connection prefab <a href="#id-3-create-a-client-connection-prefab" id="id-3-create-a-client-connection-prefab"></a>

This step is described in detail in the [Prefab setup section](https://app.gitbook.com/@docs-coherence/s/coherence/~/drafts/-Mdq8mK1otqkhY4bQpdr/get-started/prefab-setup). In short, a prefab with *CoherenceSync* and our `PlayerConnection` must be created and placed in the *Resources* directory:​

![PlayerConnection prefab](https://gblobscdn.gitbook.com/assets%2F-MWd0ZPEK7vE9nkE0b7G%2F-MdqCDf3w4s6f3x7-nqQ%2F-MdqRCkj3rMik-vFzHRx%2FScreenshot_46.png?alt=media\&token=887e5109-e8ed-4157-a9f9-7fe897e63cff)

#### 4. Binding of the method to CoherenceSync <a href="#id-2-create-a-class-that-inherits-from-the-coherenceclientconnection-class" id="id-2-create-a-class-that-inherits-from-the-coherenceclientconnection-class"></a>

Next, we have to create a bindin&#x67;*.* Navigate to *CoherenceSync* component on your prefab and press Select, in appeared window open *Methods* tab and check `OnChatMessage`:​

![Binding a client message](https://2821114902-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv0ksjqOy2jWVMwsg4f9k%2Fuploads%2F89Afyd1ey18sdVbC6ktg%2FScreenshot%202021-12-23%20at%2017.12.03.png?alt=media\&token=fe2fcf7c-629f-4de6-b8dc-9a64e91eb373)

#### 5. Link the connection prefab to the MonoBridge <a href="#id-4-link-the-connection-prefab-to-the-monobridge" id="id-4-link-the-connection-prefab-to-the-monobridge"></a>

For the system to know which object to create for every new client connection, we have to link our prefab to the *Coherence MonoBridge*. Simply drag the prefab to the `Client Connection Prefab` field in the *MonoBridge* inspector:​

![MonoBridge with linked connection prefab](https://2821114902-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fv0ksjqOy2jWVMwsg4f9k%2Fuploads%2F5EyQ3dVngx7kBYw6K306%2Fimage.png?alt=media\&token=c7035769-ffd6-4bcf-a1b2-428db1c79e98)

### Connection management <a href="#connection-management" id="connection-management"></a>

Once we have everything set up, whenever a new client joins an instance of the *connection prefab* will be created. The instantiated object resembles a client connection and will be kept alive for as long as that client remains connected to the replication server.

To get notified about the creation and destruction of connections we can use the following events:

```csharp
public class GameManager : MonoBehaviour
{
    public CoherenceMonoBridge MonoBridge;

    private void Start()
    {
        MonoBridge.OnConnectionCreated += OnConnectionCreated;
        MonoBridge.OnConnectionDestroyed += OnConnectionDestroyed;
    }

    private void OnConnectionCreated(CoherenceClientConnection clientConnection)
    {
        Debug.Log($"Client connected: {clientConnection.Id}");
    }

    private void OnConnectionDestroyed(CoherenceClientConnection clientConnection)
    {
        Debug.Log($"Client disconnected: {clientConnection.Id}");
    }
}
```

{% hint style="info" %}
The connection ID is simply an EntityID of the *connection entity.*
{% endhint %}

To get local connection or connection of any client by the ID use the following *MonoBridge* methods:

```csharp
PlayerConnection myConnection 
    = MonoBridge.GetMyConnection<PlayerConnection>();
    
PlayerConnection otherPlayerConnection 
    = MonoBridge.GetClientConnection<PlayerConnection>(otherPlayerId);
```

{% hint style="info" %}
A null may be returned by both methods if client messages are not enabled or the connection with a given ID doesn't exist.
{% endhint %}

The `CoherenceClientConnection` class exposes the following properties:

```csharp
PlayerConnection playerConnection = MonoBridge.GetMyConnection<PlayerConnection>(id);

// ID of the connection (and connection entity)
SerializeEntityID connectionId = playerConnection.Id;

// True if this is connection belongs to the local client
bool isMyConnection = playerConnection.IsMyConnection;

// CoherenceSync of the connection object
CoherenceSync sync = playerConnection.Sync;
```

### Sending client messages <a href="#sending-client-messages" id="sending-client-messages"></a>

Client messages are sent using the `SendClientMessage` method of the `CoherencePlayerConnection` class:

```csharp
private void OnConnectionCreated(CoherenceClientConnection clientConnection)
{
        clientConnection.SendClientMessage("OnChatMessage", MessageTarget.AuthorityOnly, "This is a private message");

        clientConnection.SendClientMessage("OnChatMessage", MessageTarget.All, "This is a global message");
}
```

The first message will be delivered only to the player that owns the created connection. The other message will be delivered to all instances of this connection, that is, every player (including the sender) that knows about this connection will receive this message.

If the connection ID of the message recipient is known we can use the *MonoBridge* to send a client message:

```csharp
private SerializeEntityID newestConnectionId;

private void OnConnectionCreated(CoherenceClientConnection clientConnection)
{
    if (!clientConnection.IsMyConnection)
    {
        newestConnectionId = clientConnection.Id;
    }
}

public void SendMessageToNewestConnection(string message)
{
    MonoBridge.SendClientMessage("OnChatMessage", newestConnectionId, MessageTarget.AuthorityOnly, "Hello!");
}
```
