我正在尝试使用 Tauri 应用程序中的
hidapi
板条箱读取 HID 设备(条形码扫描仪)。
我想到了这个场景:
device-disconnected
device-data
与有效负载Tauri command
重新扫描设备现在我有了这个代码
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
extern crate hidapi;
use hidapi::HidApi;
use tauri::Manager;
#[derive(Clone, serde::Serialize)]
struct Payload {
message: String,
}
#[tauri::command]
fn detect_barcode_scanner(app: &mut tauri::App) -> () {
let vid = 0x1234;
let pid = 0x5678;
match HidApi::new() {
Ok(api) => {
let mut device_found = false;
for device_info in api.device_list() {
// Check if the scanner is in the list
if device_info.vendor_id() == vid && device_info.product_id() == pid {
device_found = true;
if let Ok(device) = device_info.open_device(&api) {
println!("Barcode scanner found & opened successfully.");
// Allocate mem buffer for data
let mut mem_buf = Vec::<u8>::with_capacity(256);
// Start reading data
loop {
match device.read(&mut mem_buf) {
Ok(count) => {
let data = &mem_buf[..count];
println!("Scanned data: {:?}", data);
app.emit_all("scanner-data", Payload { message: "Tauri is awesome!".into() }).unwrap();
}
Err(e) => {
eprintln!("Error reading from HID device: {:?}", e);
break;
}
}
}
}
}
}
if !device_found {
println!("Barcode scanner not found.");
}
}
Err(e) => {
eprintln!("Error initializing HID API: {}", e);
}
}
}
fn main() {
tauri::Builder::default()
.setup(|app|{
detect_barcode_scanner(app);
Ok(())
})
.invoke_handler(tauri::generate_handler![detect_barcode_scanner])
.run(tauri::generate_context!())
.expect("failed to run app");
}
我现在遇到的问题是
emit_all
功能只能在应用程序句柄上使用,因此我从设置功能中调用功能Detect_barcode_scanner。
但这会导致
emit_all
函数发送的事件丢失,因为 UI 尚未准备好。
这也阻止我在设置后保持与设备的连接打开以继续接收消息。
有关如何解决此问题的任何指南/提示?
您希望以
async
的方式以不同的方式管理状态。
Rust 在不共享内存的情况下管理状态的范例与其他语言不同。
我建议做一个稍微简单的版本:
这是一个快速代码(未经测试):
fn main() {
let (in_tx, in_rx) = mpsc::channel(1);
let (out_tx, mut out_rx) = mpsc::channel(1);
tauri::Builder::default()
.manage(AsyncProcInputTx {
inner: Mutex::new(async_proc_input_tx),
})
.invoke_handler(tauri::generate_handler![your_function_here])
.setup(|app| {
tauri::async_runtime::spawn(async move {
async_process_model(
input_rx,
out_tx,
).await
});
let app_handle = app.handle();
tauri::async_runtime::spawn(async move {
loop {
if let Some(hid_device) = out_rx.recv().await {
// your_function_here(hid_device, &app_handle);
}
}
});
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}