amqp-rs / lapin

AMQP client library in Rust, with a clean, futures based API
MIT License
1.04k stars 92 forks source link
amqp amqp-client amqp0-9-1 async hacktoberfest messaging rust
[![API Docs](https://docs.rs/lapin/badge.svg)](https://docs.rs/lapin) [![Build status](https://github.com/amqp-rs/lapin/workflows/Build%20and%20test/badge.svg)](https://github.com/amqp-rs/lapin/actions) [![Downloads](https://img.shields.io/crates/d/lapin.svg)](https://crates.io/crates/lapin) [![Coverage Status](https://coveralls.io/repos/github/amqp-rs/lapin/badge.svg?branch=main)](https://coveralls.io/github/amqp-rs/lapin?branch=main) [![Dependency Status](https://deps.rs/repo/github/amqp-rs/lapin/status.svg)](https://deps.rs/repo/github/amqp-rs/lapin) [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) A Rust AMQP client library.


This project follows the AMQP 0.9.1 specifications, targeting especially RabbitMQ.

Features

TLS backends

Rustls certificates store

Warning about crypto backends for rustls

A crypto implementation must be enabled in rustls using feature flags. We mimic what rustls does, providing one feature flag per implementation and enabling the same as rustls by default. Available options are:

Integration with third-party runtimes

Lapin can use any runtime of your choice by passing it to the ConnectionProperties.

You can configure the executor to use through executor-trait.

You can configure the reactor to use through reactor-trait.

There are implementations for tokio, async-std and others.

Example

use futures_lite::stream::StreamExt;
use lapin::{
    options::*, publisher_confirm::Confirmation, types::FieldTable, BasicProperties, Connection,
    ConnectionProperties, Result,
};
use tracing::info;

fn main() -> Result<()> {
    if std::env::var("RUST_LOG").is_err() {
        std::env::set_var("RUST_LOG", "info");
    }

    tracing_subscriber::fmt::init();

    let addr = std::env::var("AMQP_ADDR").unwrap_or_else(|_| "amqp://127.0.0.1:5672/%2f".into());

    async_global_executor::block_on(async {
        let conn = Connection::connect(
            &addr,
            ConnectionProperties::default(),
        )
        .await?;

        info!("CONNECTED");

        let channel_a = conn.create_channel().await?;
        let channel_b = conn.create_channel().await?;

        let queue = channel_a
            .queue_declare(
                "hello",
                QueueDeclareOptions::default(),
                FieldTable::default(),
            )
            .await?;

        info!(?queue, "Declared queue");

        let mut consumer = channel_b
            .basic_consume(
                "hello",
                "my_consumer",
                BasicConsumeOptions::default(),
                FieldTable::default(),
            )
            .await?;
        async_global_executor::spawn(async move {
            info!("will consume");
            while let Some(delivery) = consumer.next().await {
                let delivery = delivery.expect("error in consumer");
                delivery
                    .ack(BasicAckOptions::default())
                    .await
                    .expect("ack");
            }
        }).detach();

        let payload = b"Hello world!";

        loop {
            let confirm = channel_a
                .basic_publish(
                    "",
                    "hello",
                    BasicPublishOptions::default(),
                    payload,
                    BasicProperties::default(),
                )
                .await?
                .await?;
            assert_eq!(confirm, Confirmation::NotRequested);
        }
    })
}