Verbara.Sdk.Ari
2.9.0
dotnet add package Verbara.Sdk.Ari --version 2.9.0
NuGet\Install-Package Verbara.Sdk.Ari -Version 2.9.0
<PackageReference Include="Verbara.Sdk.Ari" Version="2.9.0" />
<PackageVersion Include="Verbara.Sdk.Ari" Version="2.9.0" />
<PackageReference Include="Verbara.Sdk.Ari" />
paket add Verbara.Sdk.Ari --version 2.9.0
#r "nuget: Verbara.Sdk.Ari, 2.9.0"
#:package Verbara.Sdk.Ari@2.9.0
#addin nuget:?package=Verbara.Sdk.Ari&version=2.9.0
#tool nuget:?package=Verbara.Sdk.Ari&version=2.9.0
Verbara.Sdk.Ari
Asterisk REST Interface (ARI) client for .NET 10 with Native AOT support.
Features
- REST client for all 8 ARI resources (Channels, Bridges, Playbacks, Recordings, Endpoints, Applications, Sounds, DeviceStates)
- WebSocket event streaming with 46 event types
- AOT-safe JSON serialization via
System.Text.Jsonsource generation - Automatic reconnection with exponential backoff
- AudioSocket server for real-time audio streaming
System.Diagnostics.Metricsfor observability
Quick Start
var client = new AriClient(Options.Create(new AriClientOptions
{
BaseUrl = "http://pbx.example.com:8088",
Username = "admin",
Password = "secret",
Application = "myapp"
}), logger);
await client.ConnectAsync();
// Subscribe to events
client.Subscribe(Observer.Create<AriEvent>(evt =>
{
if (evt is StasisStartEvent start)
Console.WriteLine($"Channel entered Stasis: {start.Channel?.Name}");
}));
// REST operations
var channels = await client.Channels.ListAsync();
var bridge = await client.Bridges.CreateAsync("mixing", "mybridge");
await client.Bridges.AddChannelAsync(bridge.Id!, channels[0].Id!);
The token you hand ConnectAsync bounds the dial only: cancelling it once the connect has returned (a host's start
or stopping token, a request token) does not end the connection, its events or a reconnect. End the connection with
DisconnectAsync or by disposing the client.
Closing
Every ending the SDK starts on an open WebSocket sends a close frame first, and every close Asterisk sends is answered:
DisconnectAsyncsends its close before the events loop stops reading, then waits for Asterisk's answering close up to the existing 5-second bound, or until the token you passed is cancelled, whichever comes first. The token never suppresses the frame: a disconnect whose token is already cancelled (a host's stopping token in afinally) still sends it, then lets the connection go without waiting. A disconnect does not start a reconnect, even withAutoReconnecton.- A close Asterisk sends is answered with one close before the socket is released and before any reconnect the
AutoReconnectpolicy allows. WithAutoReconnectoff the client then readsDisconnected. - Disposing the client while it reconnects (in its backoff, or in a dial the far end holds) ends with
Disconnected, as a disposal of a connected client does. AriOutboundListener.StopAsyncstops accepting, sends every open connection its close at the same time and waits for the answers under one shared one-second bound; the stop's token can end that wait but never suppresses a frame. A connection that has not answered by then is aborted before it is released. Every connection's end logsConnection closed(Debug); an idle timeout also logsIdle timeout(Warning); a stop, or a close bound that runs out during a stop or the connection's own disconnect, logs no error. Only a transport failure logsConnection error(Error).
What this costs, measured on Asterisk 22.12.0-rc2, 23.6.0-rc2 and 24.0.0-rc2 against the full functional test stack:
| Ending | Result | Latency |
|---|---|---|
A client close on /ari/events (settled, right after connect, events flowing; 100 runs per cell, two independent runs) |
Asterisk answered 900/900 in each run | answer p50 at most 0.19 ms, max 7.9 ms |
| A close sent to Asterisk's outbound WebSocket client, 1, 10 or 50 connections at once (10 rounds each, two independent runs) | Asterisk answered 1,830/1,830 in each run | answer max 6.5 ms with 50 connections |
A generic host stopping 1 or 10 AriConnectionHostedService instances (20 stops each) |
660/660 sessions ended Disconnected |
stop p50 0.16–0.19 ms (1), 0.55–0.65 ms (10), max 7.1 ms |
The bounds are there for an Asterisk, proxy or network that does not answer; none of these runs came near them.
Connection attempts
One ConnectAsync call or automatic reconnect attempt can open more than one TCP connection within the existing
five-second connect bound. The .NET HTTP transport can retry a connection that closes before an upgrade response;
these transport retries are separate from the ARI client's automatic reconnect policy.
With .NET SDK 10.0.402 and runtime 10.0.13, twenty independent failed caller dials per loopback-peer shape recorded:
| Peer behavior | TCP connections per caller dial |
|---|---|
| Accept, then close immediately with FIN | 4 |
| Accept, then reset immediately with RST | 1–4 |
| Reply HTTP 401 or HTTP 503 | 1 |
These are measured framework-specific counts, pinned by AriDialConnectionCountTests; a framework upgrade may
change them. They are not a runtime-independent limit for every network. Measurements against Asterisk on the same
framework also found one TCP connection for a wrong password or direct refusal, and one to four when a proxy accepted
and closed while Asterisk was stopped. Additional starts matched HTTP transport retry events; no extra SDK retry layer
was observed. The client does not suppress or replace the runtime's transport retries.
Documentation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Configuration.Abstractions (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- System.Reactive (>= 7.0.0)
- Verbara.Sdk (>= 2.9.0)
- Verbara.Sdk.Resilience (>= 2.9.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Verbara.Sdk.Ari:
| Package | Downloads |
|---|---|
|
Verbara.Sdk.Activities
Activities - high-level telephony operations: Dial, Hold, Transfer, Park, Bridge, Conference |
|
|
Verbara.Sdk.Hosting
Verbara.Sdk.Hosting - DI extensions and meta-package referencing all Verbara Sdk sub-packages |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.9.0 | 522 | 10/29/2026 |
| 2.8.0 | 2,952 | 10/9/2026 |
| 2.7.0 | 764 | 10/3/2026 |
| 2.6.1 | 502 | 9/30/2026 |
| 2.6.0 | 735 | 9/24/2026 |
| 2.5.3 | 636 | 9/13/2026 |
| 2.5.2 | 281 | 9/13/2026 |
| 2.5.1 | 308 | 9/12/2026 |
| 2.5.0 | 390 | 8/25/2026 |
| 2.4.0 | 1,982 | 7/27/2026 |
| 2.3.2 | 692 | 7/20/2026 |
| 2.3.1 | 331 | 7/14/2026 |
| 2.3.0 | 435 | 7/6/2026 |
| 2.2.1 | 905 | 5/23/2026 |
| 2.2.0 | 182 | 5/20/2026 |
| 2.1.2 | 184 | 5/8/2026 |
| 2.1.1 | 156 | 5/7/2026 |
| 2.1.0 | 3,438 | 5/7/2026 |
| 2.0.0 | 171 | 5/6/2026 |