Asterisk Manager (asterisk-manager)
A modern, asynchronous, strongly-typed, and stream-based library for interacting with the Asterisk Manager Interface (AMI) in Rust.
This crate simplifies communication with AMI by handling connection, authentication, sending actions, and consuming events in an idiomatic Rust way, using Tokio and a type system that helps prevent compile-time errors.
Table of Contents
- ✨ Features
- 🚀 Getting Started
- 📖 Core Concepts
- 🔌 Reconnection Strategy
- 🤝 Contributing
- 📜 License
- ⭐ Acknowledgements
✨ Features
- Strongly-Typed AMI Messages: Actions, Events, and Responses are modeled as Rust
enums andstructs. This reduces runtime errors, improves safety, and enables powerful autocompletion in your editor. - Stream-Based API: Consume AMI events reactively and efficiently using the
Streamabstraction fromtokio_stream, integrating seamlessly with the Tokio ecosystem. - Fully Asynchronous: Built on Tokio for non-blocking, high-performance operations, ideal for concurrent applications.
- Action-Response Correlation: Send an action and receive a
Futurethat resolves to the corresponding response, making request/response logic straightforward. - Detailed Error Handling: A comprehensive
AmiErrorenum allows robust handling of different failure scenarios (I/O, authentication, parsing, timeouts, etc.).
🚀 Getting Started
1. Installation
Add asterisk-manager to your Cargo.toml. The library requires Tokio as the async runtime.
[]
= "1.0.0" # Replace with the latest version
= { = "1", = ["full"] }
= "0.1"
= "0.4"
The dependencies serde, serde_json, and uuid are managed by asterisk-manager.
2. Usage Example
This example connects to AMI, listens for events in a separate task, sends a Ping action, and awaits the response.
use ;
use StreamExt;
use Duration;
async
📖 Core Concepts
The Manager
The Manager struct is the main entry point of the library. It acts as a handle for the AMI connection. Internally, it manages connection state, authentication, and a background I/O task that reads and processes all messages from the Asterisk server.
Manager is Clone, Send, and Sync, allowing it to be safely shared between multiple tasks, such as in a web application using Actix Web or Axum.
Sending Actions
To send an action to Asterisk, use the manager.send_action() method. It accepts an instance of the AmiAction enum and returns a Future.
let action = Command ;
let response_result = manager.send_action.await;
The Future resolves to a Result<AmiResponse, AmiError>. This allows you to asynchronously await the direct response to your action (e.g., Response: Success or Response: Error).
Consuming Events
The library uses a "fan-out" approach for events. A single I/O task reads all events from Asterisk and broadcasts them to all interested consumers via a broadcast::channel.
To consume events, obtain a stream with manager.all_events_stream().await.
let mut stream = manager.all_events_stream.await;
while let Some = stream.next.await
This allows multiple parts of your application to independently and concurrently listen to the same AMI events.
Error Handling
All fallible operations return Result<T, AmiError>. The AmiError enum describes the error source, allowing granular failure handling.
match manager.connect_and_login.await
🔌 Reconnection Strategy
This library does not include built-in automatic reconnection logic by design. The philosophy is to provide robust building blocks so you can implement the reconnection strategy that best fits your application (e.g., exponential backoff, fixed number of attempts, etc.).
The Manager exposes the necessary methods and error types (AmiError::ConnectionClosed, AmiError::Io) to detect a disconnection and trigger your reconnection logic.
For a complete and robust example of a web application with resilient reconnection logic, see the examples/actix_web_example.rs file in this repository.
🤝 Contributing
Contributions are very welcome! If you find a bug, have a suggestion for improvement, or want to add support for more actions and events, feel free to open an Issue or a Pull Request.
📜 License
This project is licensed under the MIT License.
⭐ Acknowledgements
This work was inspired by the simplicity and effectiveness of the following libraries:
- [NodeJS-AsteriskManager](https://github.com/pipobscure/NodeJS-AsteriskManager)
- [node-asterisk](https://github.com/mscdex/node-asterisk)
- Thanks to all contributors and the Rust community.