Does rust have global variables

I have a websoket connection, and I hope other processes will actively send messages to the server, but rust can't get the sending object in the global variable at all

websocket.rs


use std::{sync::{Mutex}};
use tungstenite::{connect, Message};
use crate::store::global_store::WEBS_IPC;

pub static  WEBS_IPC: OnceCell<Mutex<WebSocket<MaybeTlsStream<TcpStream>>>> = OnceCell::new();

/**
 * init websocket
 */
pub async  fn init_websocket ()  {

    // 连地址
    let url = url::Url::parse("ws://myhost.com").unwrap();
    let ( socket, response) =connect(url).expect("Can't connect");
    WEBS_IPC.set(Mutex::new(socket));
    tokio::spawn(handle_connection());
}


pub async fn handle_connection () {
    let  socket = WEBS_IPC.get().unwrap();
    loop {
        let mut c = socket.lock().unwrap();
        let msg = c.read_message().expect("Error reading message");
        println!("Received: {}", msg);
    }

}


#[tokio::main]
pub async fn send_msg (msg:String) {
    let  socket = WEBS_IPC.get().unwrap();
    let  mut c = socket.lock().unwrap();
    c.write_message(Message::Text("Hello WebSocket".into())).unwrap();
}



msg_send.rs

        // init websocket
        init_websocket().await;
        // send msg
        send_msg("test".to_string());

But reading the server message in this way has been blocking the lock, unable to send the message, I'm going crazy!

I think the biggest problem with this, though the code is somewhat incomplete so I’m not sure, is that it mixes synchronous I/O into async functions. Mixing them without potential deadlocks requires more care than that.

Basically, if you’re working with Tokio, any I/O or locking should use an await. If they aren’t, it means your using the synchronous version.

to add to notridlle reply, you may want to use tokio's Mutex, which alows to await on a lock call.
that by itself won't fix the issue however, in the handle_connection function you're acquiring a lock, and then entering an inifnite loop, meaning the lock is never realeased. You should move the lock call to inside the loop, so that other threads are capable of acquiring it.

from the std docs:

An RAII guard is returned to allow scoped unlock of the lock. When the guard goes out of scope, the mutex will be unlocked.
The exact behavior on locking a mutex in the thread which already holds the lock is left unspecified. However, this function will not return on the second call (it might panic or deadlock, for example).