一些朋友和我目前正在网站上做一个在线乒乓游戏. 游戏运行良好,但我想做一个Rust CLI应用程序,允许用户玩与在线玩家在网站上.
为此,我使用了钨合金板条的websocket.我还使用ncurses crate获取用户输入,term_size crate获取终端的大小,以适应游戏的渲染方式.
我与websocket服务器的连接正常,但是当我调整终端的大小以测试"响应"是否正常工作时,我得到了一个os错误4,这是中断的系统调用.经过一些研究,我发现当操作系统中断终端时,操作系统会发送一个SIGWINCH信号给进程,中断每个阻塞的系统调用. 我知道在sync crate中有钨合金(所以我的websocket被阻塞了),这就是为什么我 Select 它而不是tokio(这是我的第一个Rust应用程序,我不想在我不熟悉语言的时候用线程和javoc代码使它复杂化).
我真的不知道如何禁用这个信号(我不认为这样做是一个好主意),或者如何以一种不会中断阻塞系统调用的方式处理它.我也不确定禁用SIGWINCH是否不会" destruct "term_size crate.
这是我代码的一部分:
initscr();
raw();
keypad(stdscr(), true);
noecho();
timeout(0);
loop {
match getch() {
27 => { // ESC
endwin();
break;
},
ch => {
let ch = match char::from_u32(ch as u32) {
Some(ch) => {
ch
},
None => ' '
};
if ch != ' ' { // Send user input to the server
socket.write_message(Message::Text(r#"{"message":"{ch}"}"#.to_string().replace("{ch}", &ch.to_string())));
}
}
}
match socket.read_message() { // THIS IS WHERE THE ERROR OCCURED
Ok(msg) => match msg {
Message::Text(msg) => {
// render the game
},
_ => {}
},
Err(err) => { ... }
}
}
我试过了,但什么也没改变:
use std::os::unix::io::RawFd;
use nix::sys::signal::{self, Signal, SigHandler, SigAction, SigSet, SaFlags};
use nix::unistd::Pid;
fn main() {
let sig_action = SigAction::new(
SigHandler::SigIgn,
SaFlags::empty(),
SigSet::empty(),
);
unsafe {
let _ = signal::sigaction(Signal::SIGWINCH, &sig_action).expect("Failed to ignore SIGWINCH");
}
// The rest of my code are here (like authentification, selection to create or join a game, etc...)