Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Http 如何使用POST请求更新Actix应用程序_数据?_Http_Post_Rust_Actix Web_Rust Actix - Fatal编程技术网

Http 如何使用POST请求更新Actix应用程序_数据?

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

我正在尝试创建一个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_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())
这也是一个很好的参考