为什么我在代码中加了#[tokio::main],但仍然出现错误提示"there is no reactor running, must be called from the context of Tokio runtime"?

38

我正在遵循mdns Rust文档,并复制了示例代码,但它抛出了以下错误:

thread 'main' panicked at 'there is no reactor running, must be called from the context of Tokio runtime'

这是我拥有的代码:

use futures_util::{pin_mut, stream::StreamExt};
use mdns::{Error, Record, RecordKind};
use std::{net::IpAddr, time::Duration};

const SERVICE_NAME: &'static str = "_googlecast._tcp.local";

#[tokio::main]
async fn main() -> Result<(), Error> {
    // Iterate through responses from each Cast device, asking for new devices every 15s
    let stream = mdns::discover::all(SERVICE_NAME, Duration::from_secs(15))?.listen();
    pin_mut!(stream);

    while let Some(Ok(response)) = stream.next().await {
        let addr = response.records().filter_map(self::to_ip_addr).next();

        if let Some(addr) = addr {
            println!("found cast device at {}", addr);
        } else {
            println!("cast device does not advertise address");
        }
    }

    Ok(())
}

fn to_ip_addr(record: &Record) -> Option<IpAddr> {
    match record.kind {
        RecordKind::A(addr) => Some(addr.into()),
        RecordKind::AAAA(addr) => Some(addr.into()),
        _ => None,
    }
}

依赖项:

[dependencies]
mdns = "1.1.0"
futures-util = "0.3.8"
tokio = { version = "0.3.3", features = ["full"] }

我缺少什么?我尝试在网上寻找如何为这种情况创建反应堆,但没有找到。

5个回答

30

您正在使用更新版本的Tokio,例如0.3或1.x,而许多软件包(包括mdns 1.1.0)依赖于较旧版本的Tokio,例如0.2。

% cargo tree -d
tokio v0.2.22
└── mdns v1.1.0
    └── example_project v0.1.0

tokio v0.3.3
└── example_project v0.1.0

目前,您需要匹配Tokio运行时的版本。最简单的方法是您自己使用Tokio 0.2。在某些情况下,tokio-compat-02 crate也可能有用。

另请参见:


相同根本原因的各种错误消息:

没有运行的反应堆,在Tokio 1.x运行时的上下文中必须调用

没有运行的反应堆,在Tokio运行时的上下文中必须调用

当前未在Tokio运行时中运行


13

9

在撰写本文时,已有相当数量的 crate 使用了 Tokio v1,但其他可能仍处于实验阶段。检查您的 crate 是否有使用tokio运行时向后兼容的 预发布版本

一个相关的例子是 actix-web,自版本 4 起使用 Tokio 的运行时 1.0。虽然此主要更新的预发布版本自 2022-01-07 以来已经存在,但 4.0.0 版本直到 2022-02-25 才发布。

actix-web = { version = "4.0.0-beta.10" }

2
谢谢。我在actix-web中遇到了完全相同的错误,本来要失望地将tokio降级到0.2。我更喜欢不太稳定的beta版而非过时的<1版本。 :P - PrisionMike

0
我正在使用tokio v1.34.0,添加#[tokio::main]解决了这个问题。
#[launch]
#[tokio::main]
async fn rocket() -> _ {

-1
我运行了相同的代码,只是对依赖项进行了更改,产生了错误。
[dependencies]
mdns = "3.0.0"
futures-util = "0.3.28"
tokio = { version = "1.32.0", features 
  = ["full"] }
    
    use futures_util::{pin_mut, 
      stream::StreamExt};
    use mdns::{Error, Record, 
      RecordKind};
    use std::{net::IpAddr, 
      time::Duration};
    
    const SERVICE_NAME: &'static str = 
      "_googlecast._tcp.local";
    
    #[tokio::main]
    async fn main() -> Result<(), 
      Error> {
        // Iterate through responses from 
        // each Cast device, asking for new 
        // devices every 15s
        let stream = 
          mdns::discover::all(SERVICE_NAME, 
          Duration::from_secs(15))?.listen();
        pin_mut!(stream);
    
        while let Some(Ok(response)) = 
          stream.next().await 
        {
            let addr = 
            response.records().filter_map(  
              self::to_ip_addr).next();
    
            if let Some(addr) = addr {
                println!("found cast device 
                  at {}", addr);
            } else {
                println!("cast device does 
                  not advertise address");
            }
        }
    
        Ok(())
    }
    
    fn to_ip_addr(record: &Record) -> 
        Option<IpAddr> {
        match record.kind {
            RecordKind::A(addr) => 
              Some(addr.into()),
            RecordKind::AAAA(addr) => 
              Some(addr.into()),
            _ => None,
        }
    }

// A small sample of the output I 
// received without error is below:

found cast device at 10.0.0.165
found cast device at 10.0.0.171
found cast device at 10.0.0.158


1
这个回答需要提供更多的支持信息,并且要提供其他回答没有提供的新颖独特的内容。 - undefined
以下代码与接收以下错误的人相同: - undefined
我在原始提交中增加了更多的内容。希望这能有所帮助。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接