Rust Websocket客户端消息有效负载“;“活得不够长”;
我修改了以保存来自websocket服务器的消息负载:Rust Websocket客户端消息有效负载“;“活得不够长”;,rust,Rust,我修改了以保存来自websocket服务器的消息负载: fn main() { let mut globaltest = ""; // ...some othercode let receive_loop = thread::spawn(move || { // Receive loop for message in receiver.incoming_messages() { let message: Mes
fn main()
{
let mut globaltest = "";
// ...some othercode
let receive_loop = thread::spawn(move || {
// Receive loop
for message in receiver.incoming_messages() {
let message: Message = match message {
Ok(m) => m,
Err(e) => {
println!("Receive Loop: {:?}", e);
let _ = tx_1.send(Message::close());
return;
}
};
match message.opcode {
Type::Close => {
// Got a close message, so send a close message and return
let _ = tx_1.send(Message::close());
return;
}
Type::Ping => match tx_1.send(Message::pong(message.payload)) {
// Send a pong in response
Ok(()) => (),
Err(e) => {
println!("Receive Loop: {:?}", e);
return;
}
},
// Say what we received
_ => {
println!("Receive Loop: {:?}", message);
// recive from motion
let buf = &message.payload;
{
let s = match str::from_utf8(buf) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
println!("{}",s);
////>>> problem here <<<
globaltest = s;
}
},
}
}
});
// ...some othercode
}
我不知道为什么。我尝试了很多解决方案,如Arc
和Mutex
,但都不起作用:(
当我删除globaltest=s
时,代码构建和运行都没有问题。因此我尝试编写一个更简单的示例:
use std::str;
use std::thread;
fn main() {
let mut y = 2;
let receive_loop = thread::spawn(move || {
let x = 1;
y = x;
println!("tt{:?}",y);
});
let receive_loop2 = thread::spawn(move || {
println!("tt2{:?}",y);
});
println!("{:?}",y);
}
这是一个几乎相同的结构
以下是完整代码,与rust websocket客户端示例略有不同:
extern crate websocket;
fn main() {
use std::thread;
use std::sync::mpsc::channel;
use std::io::stdin;
use std::str;
use websocket::{Message, Sender, Receiver};
use websocket::message::Type;
use websocket::client::request::Url;
use websocket::Client;
let mut globaltest ="";
let url = Url::parse("ws://127.0.0.1:2794").unwrap();
println!("Connecting to {}", url);
let request = Client::connect(url).unwrap();
let response = request.send().unwrap(); // Send the request and retrieve a response
println!("Validating response...");
response.validate().unwrap(); // Validate the response
println!("Successfully connected");
let (mut sender, mut receiver) = response.begin().split();
let (tx, rx) = channel();
let tx_1 = tx.clone();
let send_loop = thread::spawn(move || {
loop {
// Send loop
let message: Message = match rx.recv() {
Ok(m) => m,
Err(e) => {
println!("Send Loop: {:?}", e);
return;
}
};
match message.opcode {
Type::Close => {
let _ = sender.send_message(&message);
// If it's a close message, just send it and then return.
return;
},
_ => (),
}
// Send the message
match sender.send_message(&message) {
Ok(()) => (),
Err(e) => {
println!("Send Loop: {:?}", e);
let _ = sender.send_message(&Message::close());
return;
}
}
}
});
let receive_loop = thread::spawn(move || {
// Receive loop
for message in receiver.incoming_messages() {
let message: Message = match message {
Ok(m) => m,
Err(e) => {
println!("Receive Loop: {:?}", e);
let _ = tx_1.send(Message::close());
return;
}
};
match message.opcode {
Type::Close => {
// Got a close message, so send a close message and return
let _ = tx_1.send(Message::close());
return;
}
Type::Ping => match tx_1.send(Message::pong(message.payload)) {
// Send a pong in response
Ok(()) => (),
Err(e) => {
println!("Receive Loop: {:?}", e);
return;
}
},
// Say what we received
_ => {
println!("Receive Loop: {:?}", message);
// recive from motion
let buf = &message.payload;
{
let s = match str::from_utf8(buf) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
println!("{}",s);
globaltest = s;
}
},
}
}
});
loop {
let mut input = String::new();
stdin().read_line(&mut input).unwrap();
let trimmed = input.trim();
let message = match trimmed {
"/close" => {
// Close the connection
let _ = tx.send(Message::close());
break;
}
// Send a ping
"/ping" => Message::ping(b"PING".to_vec()),
// Otherwise, just send text
_ => Message::text(trimmed.to_string()),
};
match tx.send(message) {
Ok(()) => (),
Err(e) => {
println!("Main Loop: {:?}", e);
break;
}
}
}
// We're exiting
println!("Waiting for child threads to exit");
let _ = send_loop.join();
let _ = receive_loop.join();
println!("Exited");
}
@fjh感谢您的回复 我将代码修改成这样,在
receive\u loop
中更改globaltest
,并从主线程循环访问它。我仍然得到一个令人困惑的错误,即使花了三个小时,我仍然无法解决它:(
fn main(){
让mut globaltest:Arc=Arc::new(Mutex::new(String::from(“”));
//其他一些代码。。。
让receive_loop=thread::spawn(移动| |){
//接收环路
用于接收器中的消息。传入的_消息(){
让消息:消息=匹配消息{
Ok(m)=>m,
错误(e)=>{
println!(“接收循环:{:?}”,e);
让u=tx_1.send(Message::close());
返回;
}
};
匹配message.opcode{
类型::关闭=>{
//收到关闭消息,请发送关闭消息并返回
让u=tx_1.send(Message::close());
返回;
}
类型::Ping=>match tx_1.send(Message::pong(Message.payload)){
//发一个乒乓球作为回应
好(())=>(),
错误(e)=>{
println!(“接收循环:{:?}”,e);
返回;
}
},
//说说我们收到了什么
_ => {
让mut globaltest_child=globaltest.lock().unwrap();
println!(“接收循环:{:?}”,消息);
//动静
让buf=&message.payload;
{
让s=match str::from_utf8(buf){
Ok(v)=>v,
Err(e)=>panic!(“无效的UTF-8序列:{}”,e),
};
{
//>>>如果我这样做,globaltest值将与globaltest_child相同??
*globaltest_child=String::from(s);
println!(“{:?}”,globaltest_child.clone());
}
}
},
}
}
});
循环{
让消息=消息::文本(“mtconnect”);
匹配发送(消息){
好(())=>(),
错误(e)=>{
println!(“主循环:{:?}”,e);
打破
}
}
///>>>这里有问题////
println!(“{:?}”,globaltest.clone());
线程::睡眠(时间::持续时间::from_millis(3000));
}
}
编译器总是告诉我:
athaniel@nathaniel-virtual-machine:~/rustcoderep/rsadapter$ sudo cargo run
Compiling rsadapter v0.1.0 (file:///home/nathaniel/rustcoderep/rsadapter)
src/main.rs:166:25: 166:35 error: use of moved value: `globaltest` [E0382]
src/main.rs:166 println!("{:?}",globaltest.clone());
^~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:166:9: 166:45 note: in this expansion of println! (defined in <std macros>)
src/main.rs:166:25: 166:35 help: run `rustc --explain E0382` to see a detailed explanation
src/main.rs:102:35: 153:3 note: `globaltest` moved into closure environment here because it has type `alloc::arc::Arc<std::sync::mutex::Mutex<collections::string::String>>`, which is non-copyable
src/main.rs:102 let receive_loop = thread::spawn(move || {
src/main.rs:103
src/main.rs:104
src/main.rs:105 // Receive loop
src/main.rs:106 for message in receiver.incoming_messages() {
src/main.rs:107 let message: Message = match message {
...
src/main.rs:102:35: 153:3 help: perhaps you meant to use `clone()`?
error: aborting due to previous error
athaniel@nathaniel-虚拟机:~/rustcoderep/rsadapter$sudo货物运行
编译rsadapter v0.1.0(file:///home/nathaniel/rustcoderep/rsadapter)
src/main.rs:166:25:166:35错误:使用移动值:`globaltest`[E0382]
src/main.rs:166 println!(“{:?}”,globaltest.clone());
^~~~~~~~~~
:2:25:2:56注意:在格式的扩展中\u args!
:3:1:3:54注:在此打印扩展中!(在中定义)
src/main.rs:166:9:166:45注:在println!(在中定义)的扩展中
src/main.rs:166:25:166:35帮助:运行'rustc--explain E0382'查看详细说明
src/main.rs:102:35:153:3注意:`globaltest`移到了闭包环境中,因为它的类型为`alloc::arc::arc`,这是不可复制的
src/main.rs:102 let receive_loop=thread::spawn(move | |){
src/main.rs:103
src/main.rs:104
src/main.rs:105//接收循环
src/main.rs:106用于receiver.incoming_messages()中的消息{
src/main.rs:107让消息:消息=匹配消息{
...
src/main.rs:102:35:153:3帮助:也许你想使用“clone()”?
错误:由于上一个错误而中止
我仍然无法在另一个线程中访问globaltest
当我删除globaltest=s
时,代码构建和运行都没有问题
是的,因为该赋值不安全。您正试图从其他线程中修改主线程中声明的局部变量。这可能会导致各种问题,如数据争用,这就是为什么编译器不允许您这样做
如果你不知道你想做什么,就很难说什么是解决这个问题的最佳方法。也就是说,你可以通过将
globaltest
设置为Arc
,而不是&str
,来解决这个问题,这样你就可以从两个线程安全地访问它。每当你遇到问题时,你应该花时间减少这有助于您了解问题所在,并可能删除可能使您困惑的无关细节
在这种情况下,您可以从删除所有其他match
臂开始,用panic!
调用替换它们。然后尝试用您自己的代码替换库,最后只使用标准库代码。最终,您将得到一些更小的方法来重现问题
这就是所谓的,当你问一个关于堆栈溢出的问题时,这是非常受鼓励的。但是,当你有一个你还不了解的问题时,它对你自己是100%有用的。作为一个专业程序员,你应该做这项工作
这里有一个可能的MCVE,我能创造出来
fn main() {
let mut globaltest:Arc<Mutex<String>> = Arc::new(Mutex::new(String::from("")));
//some other code...
let receive_loop = thread::spawn(move || {
// Receive loop
for message in receiver.incoming_messages() {
let message: Message = match message {
Ok(m) => m,
Err(e) => {
println!("Receive Loop: {:?}", e);
let _ = tx_1.send(Message::close());
return;
}
};
match message.opcode {
Type::Close => {
// Got a close message, so send a close message and return
let _ = tx_1.send(Message::close());
return;
}
Type::Ping => match tx_1.send(Message::pong(message.payload)) {
// Send a pong in response
Ok(()) => (),
Err(e) => {
println!("Receive Loop: {:?}", e);
return;
}
},
// Say what we received
_ => {
let mut globaltest_child = globaltest.lock().unwrap();
println!("Receive Loop: {:?}", message);
// recive from motion
let buf = &message.payload;
{
let s = match str::from_utf8(buf) {
Ok(v) => v,
Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
};
{
//>>> if I do like this, globaltest value will same like globaltest_child??
*globaltest_child = String::from(s);
println!("{:?}",globaltest_child.clone());
}
}
},
}
}
});
loop {
let message = Message::text("mtconnect");
match tx.send(message) {
Ok(()) => (),
Err(e) => {
println!("Main Loop: {:?}", e);
break;
}
}
///>>> problem here////
println!("{:?}",globaltest.clone());
thread::sleep(time::Duration::from_millis(3000));
}
}
athaniel@nathaniel-virtual-machine:~/rustcoderep/rsadapter$ sudo cargo run
Compiling rsadapter v0.1.0 (file:///home/nathaniel/rustcoderep/rsadapter)
src/main.rs:166:25: 166:35 error: use of moved value: `globaltest` [E0382]
src/main.rs:166 println!("{:?}",globaltest.clone());
^~~~~~~~~~
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
src/main.rs:166:9: 166:45 note: in this expansion of println! (defined in <std macros>)
src/main.rs:166:25: 166:35 help: run `rustc --explain E0382` to see a detailed explanation
src/main.rs:102:35: 153:3 note: `globaltest` moved into closure environment here because it has type `alloc::arc::Arc<std::sync::mutex::Mutex<collections::string::String>>`, which is non-copyable
src/main.rs:102 let receive_loop = thread::spawn(move || {
src/main.rs:103
src/main.rs:104
src/main.rs:105 // Receive loop
src/main.rs:106 for message in receiver.incoming_messages() {
src/main.rs:107 let message: Message = match message {
...
src/main.rs:102:35: 153:3 help: perhaps you meant to use `clone()`?
error: aborting due to previous error
use std::{str, thread};
fn main() {
let mut global_string = "one";
let child = thread::spawn(move || {
let payload = b"Some allocated raw data".to_vec();
let s = str::from_utf8(&payload).unwrap();
global_string = s;
});
println!("{}", global_string);
}
use std::{str, thread};
fn main() {
let mut global_string = "one".to_string();
let child = thread::spawn(move || {
let payload = b"Some allocated raw data".to_vec();
let s = str::from_utf8(&payload).unwrap();
global_string = s.to_string();
});
println!("{}", global_string);
}
use std::{str, thread};
use std::sync::{Arc, Mutex};
fn main() {
let global_string = Arc::new(Mutex::new("one".to_string()));
let inner = global_string.clone();
let child = thread::spawn(move || {
let payload = b"Some allocated raw data".to_vec();
let s = str::from_utf8(&payload).unwrap();
*inner.lock().unwrap() = s.to_string();
});
child.join().unwrap();
let s = global_string.lock().unwrap();
println!("{}", *s);
}