我是acix的新手,我正在尝试理解如何在一个线程上运行服务器,并从另一个线程发送请求。
这是我目前拥有的代码
use actix_web::{web, App, HttpResponse, HttpServer};
use std::{sync::mpsc::channel, thread};
#[actix_web::main]
async fn main() {
let (tx, rx) = channel();
thread::spawn(move || {
let srv =
HttpServer::new(|| App::new().default_service(web::to(|| HttpResponse::NotFound())))
.bind("localhost:12347")
.unwrap()
.run();
let _ = tx.send(srv);
});
reqwest::get("http://localhost:12347").await.unwrap();
let srv = rx.recv().unwrap();
srv.handle().stop(false).await;
}
它编译得很好,但是在发送请求时卡住了。看起来服务器正在运行,所以我不知道为什么我没有得到响应。
编辑:按照@Finomnis和@cafce25的建议,我将代码更改为使用任务而不是线程,并且await
编辑了.run()
的结果
use actix_web::{web, App, HttpResponse, HttpServer};
use std::{sync::mpsc::channel, thread};
#[actix_web::main]
async fn main() {
let (tx, rx) = channel();
tokio::spawn(async move {
let srv =
HttpServer::new(|| App::new().default_service(web::to(|| HttpResponse::NotFound())))
.bind("localhost:12347")
.unwrap()
.run();
let _ = tx.send(srv.handle());
srv.await.unwrap();
});
reqwest::get("http://localhost:12347").await.unwrap();
let handle = rx.recv().unwrap();
handle.stop(false).await;
}
这就解决了这个问题。我仍然很好奇是否可以在不同的线程上完成它,因为我不能在同步函数中使用await
。
1条答案
按热度按时间izkcnapc1#
您的代码中有几处错误;最大的一个问题是你从来没有
.await
run()
方法。仅凭这一点,您就不能在普通线程中运行它,它必须存在于异步任务中。
结果是:
await
edreqwest::get
你应该做什么:
还有:
.handle()
first。服务器句柄不包含对服务器的引用,而是基于智能指针。#[actix_web::main]
,就不要使用tokio::spawn
。actix-web
有自己的运行时,你需要使用actix_web::rt::spawn
。如果你想使用基于tokio
的任务,你需要使用#[tokio::main]
。actix-web
与tokio运行时兼容。(编辑:actix-web * 可能 * 与tokio::spawn()
兼容,我只是没有在任何地方找到说明它兼容的文档)修正了所有这些问题后,下面是一个工作版本: