# IAR51Client

<Badge tone="type">interface</Badge> <Badge>IAsyncDisposable</Badge> <Badge>thread-safe</Badge>

```csharp
namespace AR51.Net;

public interface IAR51Client : IAsyncDisposable
```

**Implements:** [`IAsyncDisposable`](https://learn.microsoft.com/en-us/dotnet/api/system.iasyncdisposable)

Dispose it with `await using` (or `DisposeAsync`): this stops every stream and closes every connection. Calling it again does nothing.

The AR 51 system: finds the server, connects, and gives you every service through one object. Create one with [`AR51Client.Create`](/docs/sdk-api/csharp-api/classes/ar51client/#create), subscribe to what you need, then call [`StartAsync`](#startasync).

All members are safe to call from any thread. While started, the client reconnects by itself whenever the server restarts or the network drops. Create one client and keep it for the life of your application.

:::tip[How-to]
This page is **reference** (facts only). For a walkthrough with a complete sample, see the [Connecting guide](/docs/csharp-api/connecting/).
:::

## Properties

<div className="apiPropTable apiTable">

| Property | Type | Access | Description |
|---|---|---|---|
| `State` | [`ConnectionState`](#connectionstate) | `get` | The current connection state. |
| `ServerEndPoint` | [`IPEndPoint?`](https://learn.microsoft.com/en-us/dotnet/api/system.net.ipendpoint) | `get` | The address of the AR 51 server this client is connected to, or `null` while it is not connected. |
| `Skeletons` | [`ISkeletonClient`](/docs/sdk-api/csharp-api/classes/iskeletonclient/) | `get` | Live skeletons of the people the system tracks. Started and stopped together with this client; it can also be stopped and started on its own. |
| `ObjectDetection` | [`IObjectDetectionClient`](/docs/sdk-api/csharp-api/classes/iobjectdetectionclient/) | `get` | Live tracked objects, for example props. Started and stopped together with this client; it can also be stopped and started on its own. |
| `Servers` | [`IServerClient`](/docs/sdk-api/csharp-api/classes/iserverclient/) | `get` | The AR 51 server machines: status, launch and quit the server program, start and stop tracking. |
| `Cameras` | [`ICameraClient`](/docs/sdk-api/csharp-api/classes/icameraclient/) | `get` | The cameras: list with calibration values, live preview, image settings and auto-tune. |
| `Calibration` | [`ICalibrationClient`](/docs/sdk-api/csharp-api/classes/icalibrationclient/) | `get` | Camera calibration and the tracked area (capture bounds). |
| `Recording` | [`IRecordingClient`](/docs/sdk-api/csharp-api/classes/irecordingclient/) | `get` | Recording of camera video and tracking data on the servers. |
| `Devices` | [`IDeviceClient`](/docs/sdk-api/csharp-api/classes/ideviceclient/) | `get` | The apps and devices connected to the system: headsets, Unity and Unreal apps, phones and Mocap Studio. |

</div>

## Method summary

<div className="apiTable">

| Method | Returns | |
|---|---|---|
| [`StartAsync`](#startasync) | [`Task`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) |  |
| [`StopAsync`](#stopasync) | [`Task`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task) |  |

</div>

→ Full descriptions in [Method details](#method-details) below.

## Events

Standard .NET events (`EventHandler<T>`): subscribe with `+=`, unsubscribe with `-=`. They are raised on a background thread.

<div className="apiTable">

| Event | Args | Raised when |
|---|---|---|
| `ConnectionStateChanged` | [`ConnectionStateChangedEventArgs`](#connectionstatechangedeventargs) | Raised when `State` changes. Raised on a background thread. |

</div>

<Example>

```csharp
ar51.ConnectionStateChanged += (_, e) =>
    Console.WriteLine($"Connection: {e.PreviousState} -> {e.State}");
```

</Example>

## Method details

### StartAsync

<ApiBody kind="method">

```csharp
Task StartAsync(CancellationToken cancellationToken = default);
```

Finds the AR 51 server, connects, and starts every service stream (for example `Skeletons`). Completes once connected; returns at once if already started and connected.

<Params>
<Param name="cancellationToken" type="CancellationToken" typeHref="https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken">Stops waiting. To limit the wait, pass a token with a timeout. Optional.</Param>
</Params>

<Returns type="Task" typeHref="https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task">A task that completes when the client is connected.</Returns>

<Throws>
<Throw type="OperationCanceledException" typeHref="https://learn.microsoft.com/en-us/dotnet/api/system.operationcanceledexception">`cancellationToken` was cancelled, or [`StopAsync`](#stopasync) was called, before the client connected.</Throw>
<Throw type="ObjectDisposedException" typeHref="https://learn.microsoft.com/en-us/dotnet/api/system.objectdisposedexception">The client was disposed.</Throw>
</Throws>

:::note
The client keeps trying until it connects, so with an unreachable server this waits until `cancellationToken` is cancelled. Cancelling only stops the wait: the client keeps connecting in the background until [`StopAsync`](#stopasync) or dispose.
:::

<Example>

```csharp
// Wait at most 15 seconds for the server; the client keeps trying in the background.
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(15));
try
{
    await ar51.StartAsync(timeout.Token);
}
catch (OperationCanceledException)
{
    Console.WriteLine("No AR 51 server found. Check the network or set AR51ClientOptions.Host.");
}
```

</Example>

</ApiBody>

### StopAsync

<ApiBody kind="method">

```csharp
Task StopAsync(CancellationToken cancellationToken = default);
```

Stops every service stream, disconnects, and waits until everything is closed. The client can be started again. Calling it again, or before [`StartAsync`](#startasync), does nothing.

<Params>
<Param name="cancellationToken" type="CancellationToken" typeHref="https://learn.microsoft.com/en-us/dotnet/api/system.threading.cancellationtoken">Stops waiting for the shutdown to finish; the shutdown still completes. Optional.</Param>
</Params>

<Returns type="Task" typeHref="https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task">A task that completes when everything is closed.</Returns>

:::note
Running `await foreach` loops over a service's `StreamAsync` end normally, without an exception.
:::

<Example>

```csharp
await ar51.StopAsync();    // stops every stream and disconnects; StartAsync can be called again
```

</Example>

</ApiBody>

## Related types

Small types used by this interface, documented here.

### ConnectionState

<Badge tone="type">enum</Badge>

```csharp
public enum ConnectionState
```

The connection state of an `IAR51Client`.

<div className="apiTable">

| Value | Meaning |
|---|---|
| `Disconnected = 0` | Not connected: not started, stopped, or disposed. |
| `Connecting = 1` | Looking for the server or (re)connecting to it. |
| `Connected = 2` | Connected to the server. |

</div>

### ConnectionStateChangedEventArgs

<Badge tone="type">class · sealed</Badge>

```csharp
public sealed class ConnectionStateChangedEventArgs : EventArgs
```

Data for `IAR51Client.ConnectionStateChanged`.

<div className="apiPropTable apiTable">

| Property | Type | Access | Description |
|---|---|---|---|
| `PreviousState` | [`ConnectionState`](#connectionstate) | `get` | The state before the change. |
| `State` | [`ConnectionState`](#connectionstate) | `get` | The new state. |

</div>

<details>
<summary>Constructor</summary>

```csharp
public ConnectionStateChangedEventArgs(ConnectionState previousState, ConnectionState state);
```

Creates the event data.

</details>

## See also

- [Connecting guide](/docs/csharp-api/connecting/) — walkthrough with a complete, compiled sample
- [Class index](/docs/sdk-api/csharp-api/classes/) — every AR51.Net type
- [Data conventions, threading and errors](/docs/csharp-api/conventions/)
