标签: rust-tokio

Tokio Tls 自签名证书

更新:这似乎更像是正确生成和信任自签名证书的问题

我正在使用 tokio-rs 构建服务器和客户端。我一切正常,但现在正在尝试将 SSL/TLS 添加到系统中。据我所知,我已经生成了一个自签名证书并正确安装了它,但是每次我尝试让客户端连接到服务器时,我都会收到以下错误:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Failure(Ssl(ErrorStack([Error { code: 336134278, library: "SSL routines", function: "ssl3_get_server_certificate", reason: "certificate verify failed", file: "s3_clnt.c", line: 1264 }])))', /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/result.rs:837
Run Code Online (Sandbox Code Playgroud)

我正在使用以下脚本生成 crt、key 和 pfx 文件:

openssl req -nodes -x509 -newkey rsa:2048 -config ssl.conf -extensions ext -subj /C=CA/ST=EH/L=Canadia/O=Dis/CN=localhost -keyout localhost.key -out localhost.crt -days 365
openssl pkcs12 -export -nodes -inkey localhost.key -in localhost.crt -out localhost.pfx
mv localhost.pfx ../
Run Code Online (Sandbox Code Playgroud)

使用这个配置文件

[req]
distinguished_name=dn
[ dn ]
CN=localhost
[ ext …
Run Code Online (Sandbox Code Playgroud)

ssl rust rust-tokio

2
推荐指数
1
解决办法
1976
查看次数

如何将 Tokio 线程池限制为一定数量的本机线程?

将 Tokio (v 0.1.11)n线程池限制为OS 本机线程的正确方法是什么,其中n是任意数量,最好在运行时配置?

据我所知,可以使用 usingtokio_current_thread::block_on_all代替tokio::runtokio_current_thread::spawn代替在单线程模式下使用 Tokiotokio::spawn

我想要一个类似的解决方案,但对于n >= 1.

multithreading asynchronous rust mio rust-tokio

2
推荐指数
1
解决办法
2662
查看次数

为什么 poll() 中的这个 Delay future 在我的自定义 Stream 类型中不起作用?

我想每秒打印一次“你好”。

引用文档:

期货使用基于投票的模型。未来的消费者反复调用 poll 函数。未来然后试图完成。如果未来能够完成,则返回 Async::Ready(value)。如果未来由于被内部资源(例如 TCP 套接字)阻塞而无法完成,则返回 Async::NotReady。

如果s return is ,我的poll函数返回,但没有任何内容打印到标准输出。NotReadyDelayNotReady

use futures::{Async, Future, Stream}; // 0.1.25
use std::time::{Duration, Instant};
use tokio::timer::Delay; // 0.1.15

struct SomeStream;

impl Stream for SomeStream {
    type Item = String;
    type Error = ();

    fn poll(&mut self) -> Result<Async<Option<Self::Item>>, Self::Error> {
        let when = Instant::now() + Duration::from_millis(1000);
        let mut task = Delay::new(when).map_err(|e| eprintln!("{:?}", e));
        match task.poll() {
            Ok(Async::Ready(value)) => {}
            Ok(Async::NotReady) => return Ok(Async::NotReady),
            Err(err) => return Err(()), …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio

2
推荐指数
1
解决办法
339
查看次数

初始化传递给异步代码(例如 tokio 和 hyper)的 Rust 变量

我有一个无法在编译时计算的值。它需要在任何应用程序代码运行之前进行计算,然后它只会在应用程序的整个生命周期中被读取。它还需要传递给执行者,例如处理程序tokiohyper处理程序。

我怎样才能安全、惯用地创造这样的价值,并且不会造成不必要的性能损失?

  • 如果我在 中 创建它main并将其传递给hyper,它的寿命就不够长。
  • 如果我使用 创建它lazy_static!,则仅在首次访问时才计算它。如果无法计算,那么我也不想运行应用程序的其余部分。我宁愿知道在启动应用程序时无法连接到数据库,而不是在客户端发出请求时无法连接到数据库。
  • 如果我将其设为 a static mut,那么我就无法在安全代码中使用它。

理想情况下,我想做类似的事情:

#[tokio::main]
pub async fn main() {
    let db = init_db();

    // This uses a hyper server, passes db around
    // to tokio and hyper handlers, etc.
    run_app(&db);
}
Run Code Online (Sandbox Code Playgroud)

asynchronous rust hyper rust-tokio

2
推荐指数
1
解决办法
2021
查看次数

在 rust / tokio 中合并流

tokio有一个合并数据结构,允许“合并”两个同构流并忘记出处。

impl<T, U> Stream for Merge<T, U> where
    T: Stream,
    U: Stream<Item = T::Item>, { ...
Run Code Online (Sandbox Code Playgroud)

是否存在流的代数逐点标记联合,它从 的流a和 的流b生成 的流Either a b

PS:我想答案是否定的,因为 Rust 显然没有标准的总和类型。

stream rust rust-tokio

2
推荐指数
1
解决办法
1993
查看次数

为什么我不能使用 rust tonic 并行发送多个请求?

我实现了 tonic helloworld教程。然后我尝试更改客户端代码,以便我可以在等待任何请求之前发送多个请求。

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let num_requests = 10;
    let mut client = GreeterClient::connect("http://[::1]:50051").await?;

    let mut responses = Vec::with_capacity(num_requests);
    for _ in 0..num_requests {
        let request = tonic::Request::new(HelloRequest {
            name: "Tonic".into(),
        });

        responses.push(client.say_hello(request));
    }
    for resp in responses {
        assert!(resp.await.is_ok());
    }

    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

这会导致编译错误:

error[E0499]: cannot borrow `client` as mutable more than once at a time
  --> src/client.rs:19:24
   |
19 |         responses.push(client.say_hello(request));
   |                        ^^^^^^ mutable borrow starts here in previous iteration of …
Run Code Online (Sandbox Code Playgroud)

rust rust-tokio rust-async-std

2
推荐指数
1
解决办法
1559
查看次数

为什么任务超时时不恐慌?

我设置超时为1s,但是任务执行到3s,却没有发生panic。

#代码

    #[should_panic]
    fn test_timeout() {
        let rt = create_runtime();
        let timeout_duration = StdDuration::from_secs(1);
        let sleep_duration = StdDuration::from_secs(3);

        let _guard = rt.enter();

        let timeout = time::timeout(timeout_duration, async {
            log("timeout running");
            thread::sleep(sleep_duration);
            log("timeout finsihed");
            "Ding!".to_string()
        });

        rt.block_on(timeout).unwrap();
    }

Run Code Online (Sandbox Code Playgroud)

rust rust-tokio

2
推荐指数
1
解决办法
709
查看次数

何时在不同线程上安排“.await”调用 - 以及 tokio 任务何时在线程之间移动

我想了解 Rust 中 tokio 的 async/await 线程模型。我特别想知道 async/await 何时会导致代码在不同线程上执行。

我观察到,在带async fn main注释的#[tokio::main](创建多线程运行时)中运行 async/await/join 代码会在同一线程中执行所有代码。在我开始通过 执行代码之前,我没有看到其他线程被使用tokio::spawn

一些相关文档

任务是调度程序管理的执行单元。生成任务会将其提交给 Tokio 调度程序,然后调度程序确保该任务在有工作要做时执行。生成的任务可以在生成它的同一线程上执行,也可以在不同的运行时线程上执行。任务生成后还可以在线程之间移动。(强调我的)

这表示生成的单个 tokio 任务可以在执行期间在线程之间移动。什么时候会发生这种情况?

还有block_on运行#[tokio::main]函数体的文档

这会在当前线程上运行给定的 future,阻塞直到完成,并产生其解析结果。future 内部产生的任何任务或计时器都将在运行时执行。

这可以理解为除非产生新的任务或计时器,否则给定未来的代码将全部在同一线程上运行。这是我观察到的。

异步 rust 代码是否会在.await连接调用中同时(但不是并行)进行 future,并且仅在tokio::spawn使用时安排在不同的线程上?

文档似乎另有说明,如果是这样,如何决定将执行转移到新线程?

rust rust-tokio

2
推荐指数
1
解决办法
365
查看次数

如何在期货链中使用Result类型中包含的套接字?

我有来自Tokio docs的以下工作代码,我稍微修改了一下:

// Task
let connection = io::read_exact(socket, buf_read)
    .and_then(|(socket, buf_read)| {
        println!("Do something with the received data...");
        for b in &buf_read {
            println!("{}", b);
        }

        // Write to the socket
        let buf_write = vec![19; 30];
        io::write_all(socket, buf_write)
    })
    .then(|res| {
        println!("{:?}", res); // Just for testing
        //Output: Ok((TcpStream, [19, 19, 19, ...]

        println!("Send data...");
        let buf_write = vec![18; 10]; // Fill the buffer with some data
        //
        //How to use the socket contained in res to write the data …
Run Code Online (Sandbox Code Playgroud)

future rust rust-tokio

1
推荐指数
1
解决办法
109
查看次数

期货::期货::懒惰的目的是什么?

Tokio文档中,有以下代码段:

extern crate tokio;
extern crate futures;

use futures::future::lazy;

tokio::run(lazy(|| {
    for i in 0..4 {
        tokio::spawn(lazy(move || {
            println!("Hello from task {}", i);
            Ok(())
        }));
    }

    Ok(())
}));
Run Code Online (Sandbox Code Playgroud)

对此的解释是:

lazy函数在第一次对将来进行轮询时运行关闭。在这里使用它来确保tokio::spawn从任务中调用。如果不使用lazytokio::spawn则会从任务的上下文外部调用它,从而导致错误。

尽管对Tokio有所了解,但我不确定我是否能准确理解。看来这两个lazy角色的作用略有不同,并且这种解释仅适用于一个。难道不是在这里lazy(在for循环内)第二次调用将闭包转换为未来吗?

future rust rust-tokio

1
推荐指数
1
解决办法
332
查看次数