我用打字稿编写了这段代码,现在我将其迁移到 Rust,这非常简单,如果您收到一条带有“main”值的消息,它会将连接保存在 appWebClient 变量中,并且所有消息现在都发送到此应用程序WebClient。
let appWebClient: any
const createWebServer = () => {
const wss = new WebSocket.Server({ port: 2004 }, () => {
console.log('server started')
})
wss.on('connection', ws => {
ws.on('message', data => {
let main = JSON.parse(data)
if (main.event == 'main') {
appWebClient = ws
return
}
let newData = main as unknown as WsBotEvents
appWebClient.send(JSON.stringify(newData))
})
})
wss.on('listening', () => {
console.log('server listening on port 2004')
})
}
在 Rust 代码中,我唯一能做的就是连接 websocket 服务器,
在我的 Rust 代码中,我唯一能做的就是连接 websocket 服务器,当我尝试保存连接(如果它是“main”)时,它给了我这个错误:使用移动值:
ws_sender
在循环的上一次迭代中,值移至此处
这里是完整的错误:
error[E0382]: use of moved value: `ws_sender`
--> src\main.rs:72:53
|
50 | let (ws_sender, mut ws_receiver) = ws_stream.split();
| --------- move occurs because `ws_sender` has type `SplitSink<WebSocketStream<tokio::net::TcpStream>, tokio_tungstenite::tungstenite::Message>`, which does not implement the `Copy` trait
...
53 | while let Some(Ok(Message::Text(data))) = ws_receiver.next().await {
| -------------------------------------------------- ---------------- inside of this loop
...
72 | *main_ws = Some(ws_sender);
| ^^^^^^^^^ value moved here, in previous iteration of loop
#[tokio::main]
async fn main() {
tokio::spawn(ws());
tauri::Builder::default()
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
async fn ws() {
let url = "127.0.0.1:2004";
let listener = tokio::net::TcpListener::bind(url)
.await
.expect("Failed to bind address");
println!("WebSocket server running on {}", url);
let main_ws: Arc<Mutex<Option<SplitSink<WebSocketStream<TcpStream>, Message>>>> = Arc::new(Mutex::new(None));
while let Ok((stream, _)) = listener.accept().await {
println!("WebSocket connection accepted");
let main_ws_clone = main_ws.clone();
tokio::spawn(async move {
if let Ok(ws_stream) = tokio_tungstenite::accept_async(stream).await {
println!("New WebSocket connection established");
let (ws_sender, mut ws_receiver) = ws_stream.split();
// Loop para receber mensagens do cliente
while let Some(Ok(Message::Text(data))) = ws_receiver.next().await {
let mut main_ws = main_ws_clone.lock().unwrap();
// Trate as mensagens recebidas aqui
let mut new_data: Value = serde_json::Value::Null;
match serde_json::from_str(&data) {
Ok(value) => {
new_data = value;
let event = new_data["event"].as_str().unwrap_or("");
match event {
"main" => {
*main_ws = Some(ws_sender);
println!("WebSocket connection registered as main");
}
_ => {}
}
}
Err(_) => todo!(),
};
}
}
});
}
}
我已经尝试了一切,但每种选择都会给我带来不同的错误
问题是,当连接发送多个
"main"
事件时,ws_sender
将被移动多次,但这是不可能的。您可以确保它仅移动一次,例如使用 Option
:
async fn ws() {
let url = "127.0.0.1:2004";
let listener = tokio::net::TcpListener::bind(url)
.await
.expect("Failed to bind address");
println!("WebSocket server running on {}", url);
let main_ws: Arc<Mutex<Option<SplitSink<WebSocketStream<TcpStream>, Message>>>> =
Arc::new(Mutex::new(None));
while let Ok((stream, _)) = listener.accept().await {
println!("WebSocket connection accepted");
let main_ws_clone = main_ws.clone();
tokio::spawn(async move {
if let Ok(ws_stream) = tokio_tungstenite::accept_async(stream).await {
println!("New WebSocket connection established");
let (ws_sender, mut ws_receiver) = ws_stream.split();
let mut ws_sender = Some(ws_sender);
// Loop para receber mensagens do cliente
while let Some(Ok(Message::Text(data))) = ws_receiver.next().await {
let mut main_ws = main_ws_clone.lock().unwrap();
// Trate as mensagens recebidas aqui
let mut new_data: Value = serde_json::Value::Null;
match serde_json::from_str(&data) {
Ok(value) => {
new_data = value;
let event = new_data["event"].as_str().unwrap_or("");
match event {
"main" => {
if let ws_sender @ Some(_) = ws_sender.take() {
*main_ws = ws_sender;
}
println!("WebSocket connection registered as main");
}
_ => {}
}
}
Err(_) => todo!(),
};
}
}
});
}
}