如何将值写入arc<rwlock<hashmap<>>>循环外

问题描述 投票:0回答:1

我有一个循环,其中程序通过网络套接字接收消息并将有关用户的信息(从消息中)写入“数据库?”。

#[derive(Debug)]
struct ChatUser{
    name: String,
    password: String,
}

static NEW_USER_ID: AtomicUsize = AtomicUsize::new(1);
type UserDB = Arc<RwLock<HashMap<usize, ChatUser>>>;

async fn web_socket(mut ws: WebSocket, State(state): State<UserDB>) {
    let new_id = NEW_USER_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
    while let Ok(Message::Text(message)) = ws.next().await.unwrap(){
        let user_info: Value = serde_json::from_str(&message.trim()).unwrap();
            let (name, password) = (user_info["name"].to_string(),    user_info["password"].to_string());
            state.write().await.insert(new_id, ChatUser { name: name, password: password }).expect("cant write"); 
            println!("{:?}",state);
    }
}

state.write 在循环中运行时无法正常工作...在循环之外一切正常

是否可以从循环中取出值?或者以其他方式将它们写在状态中?

如果我运行代码并向套接字发送消息

thread 'tokio-runtime-worker' panicked at src/main.rs:41:93:
cant write
stack backtrace:
   0: rust_begin_unwind
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/std/src/panicking.rs:652:5
   1: core::panicking::panic_fmt
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:72:14
   2: core::panicking::panic_display
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/panicking.rs:262:5
   3: core::option::expect_failed
             at /rustc/3f5fd8dd41153bc5fdca9427e9e05be2c767ba23/library/core/src/option.rs:1995:5
   4: core::option::Option<T>::expect [............]

我该如何修复它?

“不会写”<--- is the message form state.write.await.insert.expect("can't write")

rust rust-cargo rust-tokio
1个回答
0
投票

您可以将

while
循环更改为
loop
循环,以及
break
具有值的循环

async fn web_socket(mut ws: WebSocket, State(state): State<UserDB>) {
    let new_id = NEW_USER_ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
    let error = loop{
        if let Ok(Message::Text(message)) = ws.next().await.unwrap() {
            let user_info: Value = serde_json::from_str(&message.trim()).unwrap();
            let (name, password) = (
                user_info["name"].to_string(),
                user_info["password"].to_string(),
            );
            if let Err(e) = state
                .write()
                .await
                .insert(new_id, ChatUser { name, password })
            {
                // break away the loop with an error
                break e;
            };
        }else{
            // handle when ws recived message error
            return;
        };
    };
    println!("{:?}", error);
}
© www.soinside.com 2019 - 2024. All rights reserved.