首页 > 解决方案 > 使用 rust amiquip 为兔子客户端打开 tls 流

问题描述

我正在尝试启用 TLS 功能以在流上打开加密的 AMQP 连接。在 amiquip crate 文档中,有一个示例https://docs.rs/amiquip/0.3.0/amiquip/struct.Connection.html#examples

我复制了代码示例并tcp_stream尽可能简单地实现了所请求的函数,只返回所述mio::net::TcpStream实例。

use amiquip::{Auth, Connection, ConnectionOptions, ConnectionTuning, Result};
use mio::net::TcpStream;
use std::net::SocketAddr;
use std::{io::Read, time::Duration};

// Examples below assume a helper function to open a TcpStream from an address string with
// a signature like this is available:
fn tcp_stream() -> mio::net::TcpStream {
    let address: SocketAddr = "127.0.0.0:5671".parse().unwrap();
    mio::net::TcpStream::connect(address).unwrap()
}

fn main() -> Result<()> {
    // Empty amqp URL is equivalent to default options; handy for initial debugging and
    // development.
    // let temp = Connection::open_tls_stream(connector, domain, stream, options, tuning)
    let conn1 = Connection::insecure_open("amqp://")?;
    let conn1 = Connection::insecure_open_stream(
        tcp_stream(),
        ConnectionOptions::<Auth>::default(),
        ConnectionTuning::default(),
    )?;

    // All possible options specified in the URL except auth_mechanism=external (which would
    // override the username and password).
    let conn3 = Connection::insecure_open(
        "amqp://user:pass@example.com:12345/myvhost?heartbeat=30&channel_max=1024&connection_timeout=10000",
    )?;
    let conn3 = Connection::insecure_open_stream(
        tcp_stream(),
        ConnectionOptions::default()
            .auth(Auth::Plain {
                username: "user".to_string(),
                password: "pass".to_string(),
            })
            .heartbeat(30)
            .channel_max(1024)
            .connection_timeout(Some(Duration::from_millis(10_000))),
        ConnectionTuning::default(),
    )?;
    Ok(())
}

但是,我得到编译错误(在每个版本的板条箱上)如下

error[E0277]: the trait bound `mio::net::TcpStream: IoStream` is not satisfied
   --> src\main.rs:28:17
    |
28  |     let conn3 = Connection::insecure_open_stream(
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `IoStream` is not implemented for `mio::net::TcpStream`
    | 
   ::: C:\Users\Tamir Cohen\.cargo\registry\src\github.com-1ecc6299db9ec823\amiquip-0.3.3\src\connection.rs:283:48
    |
283 |     pub fn insecure_open_stream<Auth: Sasl, S: IoStream>(
    |                                                -------- required by this bound in `Connection::insecure_open_stream`

我就是不知道出了什么问题。

标签: rustrabbitmqtls1.2amqp

解决方案


你用的是哪个版本的mio?您应该使用 mio 0.6 版,例如 crate amiquip。

货物档案:

[package]
name = "message-broker"
version = "0.1.0"
edition = "2018"

[dependencies]
amiquip = "0.4.0"
mio = { version = "0.6.23" }
native-tls = "0.2.8"

带有 tls 的代码:

use amiquip::{Auth, Connection, ConnectionOptions, ConnectionTuning, Exchange, Publish, Result};
use mio::net::TcpStream;
use native_tls::TlsConnector;
use std::time::Duration;

fn tcp_stream(addr: &str) -> Result<TcpStream> {
    Ok(TcpStream::connect(&addr.parse().unwrap()).unwrap())
}

fn main() -> Result<()> {
    let mut connection = Connection::open_tls_stream(
        TlsConnector::new().unwrap(),
        "domain",
        tcp_stream("127.0.0.0:5671")?,
        ConnectionOptions::default()
            .auth(Auth::Plain {
                username: "user".to_string(),
                password: "pass".to_string(),
            })
            .heartbeat(30)
            .channel_max(1024)
            .connection_timeout(Some(Duration::from_millis(10_000))),
        ConnectionTuning::default(),
    )?;

    let channel = connection.open_channel(None)?;

    let exchange = Exchange::direct(&channel);

    exchange.publish(Publish::new("hello there".as_bytes(), "hello"))?;

    connection.close()
}

推荐阅读