Http 如何使用POST请求更新Actix应用程序_数据?
我正在尝试创建一个Actix服务器,我想将其用作全局HashMap的接口 我已经能够创建一个返回整个结构的路由。但是,现在我在更新HashMap时遇到了问题。我能够提交和接收POST请求,但是在尝试使用发布路由和get_topics路由之后,得到的HashMap是空的{}Http 如何使用POST请求更新Actix应用程序_数据?,http,post,rust,actix-web,rust-actix,Http,Post,Rust,Actix Web,Rust Actix,我正在尝试创建一个Actix服务器,我想将其用作全局HashMap的接口 我已经能够创建一个返回整个结构的路由。但是,现在我在更新HashMap时遇到了问题。我能够提交和接收POST请求,但是在尝试使用发布路由和get_topics路由之后,得到的HashMap是空的{} // Publish to topic (creating new topic if none of the same name exists, else update the data) async fn publish_t
// Publish to topic (creating new topic if none of the same name exists, else update the data)
async fn publish_topic(
topics: web::Data<Mutex<Map<String, Value>>>,
body: web::Bytes,
) -> Result<HttpResponse, Error> {
let result = serde_json::from_str(std::str::from_utf8(&body).unwrap());
let publish_req: Info = match result {
Ok(v) => v,
Err(e) => Info {
topic: "_".to_string(),
data: json!(e.to_string()),
},
};
println!("[ SERVER ]: POST Req: {:?}", publish_req);
topics
.lock()
.unwrap()
.insert(publish_req.topic, publish_req.data);
let map = topics.lock().unwrap().clone();
println!("\n\n{:?}\n\n", topics.lock().unwrap());
let body = serde_json::to_string_pretty(&map).unwrap();
return Ok(HttpResponse::Ok().json(body));
}
#[actix_web::main]
pub async fn start_server() {
std::env::set_var("RUST_LOG", "actix_web=info");
env_logger::init();
let (tx, _) = mpsc::channel();
thread::spawn(move || {
let sys = System::new("http-server");
let srv = HttpServer::new(move || {
let topics: web::Data<Mutex<Map<String, Value>>> =
web::Data::new(Mutex::new(Map::new()));
App::new()
.app_data(topics.clone()) // add shared state
// enable logger
.wrap(middleware::Logger::default())
// register simple handler
.service(web::resource("/").route(web::get().to(get_topics)))
.service(web::resource("/publish").route(web::post().to(publish_topic)))
})
.bind("127.0.0.1:8080")?
.run();
let _ = tx.send(srv);
sys.run()
});
}
//发布到主题(如果不存在同名主题,则创建新主题,否则更新数据)
异步fn发布主题(
主题:web::Data,
正文:web::字节,
)->结果{
让result=serde_json::from_str(std::str::from_utf8(&body).unwrap());
让发布请求:信息=匹配结果{
Ok(v)=>v,
错误(e)=>信息{
主题:“u.”至_字符串(),
数据:json!(例如to_string()),
},
};
println!(“[服务器]:POST请求:{:?}”,发布请求);
话题
.lock()
.unwrap()
.插入(发布请求主题、发布请求数据);
让map=topics.lock().unwrap().clone();
println!(“\n\n{:?}\n\n”,topics.lock().unwrap());
让body=serde_json::to_string_pretty(&map).unwrap();
返回Ok(HttpResponse::Ok().json(body));
}
#[actix_web::main]
发布异步fn启动\u服务器(){
std::env::set_var(“RUST_LOG”,“actix_web=info”);
环境记录器::init();
let(tx,u)=mpsc::channel();
线程::生成(移动| |{
让sys=System::new(“http服务器”);
让srv=HttpServer::new(move | |){
让主题:web::Data=
web::Data::new(Mutex::new(Map::new());
App::new()
.app_数据(topics.clone())//添加共享状态
//启用记录器
.wrap(中间件::记录器::默认值())
//寄存器简单处理程序
.service(web::resource(“/”).route(web::get().to(get_主题)))
.service(web::resource(“/publish”).route(web::post().to(publish_topic)))
})
.bind(“127.0.0.1:8080”)?
.run();
让ux=tx.send(srv);
sys.run()
});
}
好吧,你的问题源于你的方法。让我们看看下面这行:
let srv = HttpServer::new(move || {
let topics: web::Data<Mutex<Map<String, Value>>> =
web::Data::new(Mutex::new(Map::new()));
...
让srv=HttpServer::new(移动| |){
让主题:web::Data=
web::Data::new(Mutex::new(Map::new());
...
由于actix web如何使用创建新的http服务器,这告诉它在每个线程中创建一个新的主题地图。我猜这不是您自己想要做的。
要解决您的问题,您需要为所有已启动的线程创建主题的实例。这将起作用:
let topics: web::Data<Mutex<Map<String, Value>>> =
web::Data::new(Mutex::new(Map::new()));
HttpServer::new(move || {
App::new()
.app_data(topics.clone())
let主题:web::Data=
web::Data::new(Mutex::new(Map::new());
HttpServer::新建(移动| |{
App::new()
.app_数据(topics.clone())
这也是一个很好的参考