我是 rust 新手,所以这是一个关于 tauri + rust 的问题。 我正在尝试构建这个应用程序,其中有一个命令启动一个线程,该线程向rabbitmq发布许多消息,然后在发布完成后发出一个事件。 我有一个使用
ConnectionMutex
的状态 API 的托管 tauri
结构,并且我还获取了窗口句柄来发出事件。
代码如下所示:
use tauri::async_runtime::Mutex;
pub struct ConnectionMutex(pub Mutex<Option<RabbitMqConnection>>);
#[tauri::command]
pub async fn publish_message(
connection_mutex: tauri::State<'_, ConnectionMutex>,
window: tauri::Window,
) -> Result<(), String> {
tauri::async_runtime::spawn(async move {
let lock = connection_mutex
.0
.try_lock()
.map_err(|_| String::from("cannot change connection while it is being used"))
.unwrap();
let conn = lock.as_ref().ok_or("no rabbitmq connection").unwrap();
let _ = rabbitmq::publishing::publish(
&conn.target,
&conn.channel,
window,
)
.await;
});
Ok(())
}
我收到编译器错误:
borrowed data escapes outside of function
。这个错误对我来说是有意义的,我明白为什么这不安全,因为 rust 借用检查器无法再跟踪借用的变量,并且无法在正确的时间释放它。
然而,我不知道在 Rust 中实现这种东西的正确方法。
我还尝试将
State
变量的生命周期设置为静态,如下所示:
#[tauri::command]
pub async fn publish_message(
connection_mutex: tauri::State<'static, ConnectionMutex>,
window: tauri::Window,
) -> Result<(), String>
但我得到了一个不同的错误:
__tauri_message__ does not live long enough
感谢您的帮助!
一种常见的方法是将
Mutex
包装在 Arc
中,以便您可以跨 Mutex
任务安全地共享对底层 async
的引用。 (另请参阅文档中的示例)。
所以你的
ConnectionMutex
可能看起来像:
#[derive(Clone)]
pub struct ConnectionMutex(pub Arc<Mutex<Option<RabbitMqConnection>>>);
然后,当您想要在生成
async
任务时传递连接时,您首先 clone()
ConnectionMutex
为任务提供它自己的引用副本。
#[tauri::command]
pub async fn publish_message(
connection_mutex: tauri::State<'_, ConnectionMutex>,
window: tauri::Window,
) -> Result<(), String> {
let connection = connection_mutex.clone();
tauri::async_runtime::spawn(async move {
let lock = connection
.0
.try_lock()
.map_err(|_| String::from("cannot change connection while it is being used"))
.unwrap();
let conn = lock.as_ref().ok_or("no rabbitmq connection").unwrap();
let _ = rabbitmq::publishing::publish(
&conn.target,
&conn.channel,
window,
)
.await;
});
Ok(())
}