Use channel for server messages in client threads
This commit is contained in:
parent
3725457134
commit
b7ca43be33
@ -7,6 +7,7 @@ use shakmaty::{Chess, Color, Outcome, Position, Setup};
|
|||||||
use std::io;
|
use std::io;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::mpsc::{channel, Receiver, TryRecvError};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time;
|
use std::time;
|
||||||
@ -16,7 +17,7 @@ struct Client {
|
|||||||
side: Color,
|
side: Color,
|
||||||
running: Arc<AtomicBool>,
|
running: Arc<AtomicBool>,
|
||||||
input_buffer: Arc<Mutex<String>>,
|
input_buffer: Arc<Mutex<String>>,
|
||||||
server_message: Arc<Mutex<String>>,
|
server_message_recv: Receiver<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
@ -38,7 +39,7 @@ fn main() {
|
|||||||
clichess::write_to_stream(&mut stream, username_pubkey_json.to_string()).unwrap();
|
clichess::write_to_stream(&mut stream, username_pubkey_json.to_string()).unwrap();
|
||||||
let input_buffer = setup_input_buffer();
|
let input_buffer = setup_input_buffer();
|
||||||
//start a thread to listen to server messages
|
//start a thread to listen to server messages
|
||||||
let server_message = setup_server_message_recv(&stream).unwrap();
|
let server_message_recv = setup_server_message_recv(&stream).unwrap();
|
||||||
|
|
||||||
let mut client = Client {
|
let mut client = Client {
|
||||||
player: clichess::Player {
|
player: clichess::Player {
|
||||||
@ -49,7 +50,7 @@ fn main() {
|
|||||||
side: Color::White,
|
side: Color::White,
|
||||||
running: running.clone(),
|
running: running.clone(),
|
||||||
input_buffer: input_buffer.clone(),
|
input_buffer: input_buffer.clone(),
|
||||||
server_message: server_message.clone(),
|
server_message_recv,
|
||||||
};
|
};
|
||||||
|
|
||||||
match prompt_user_for_role(&client, &mut stream) {
|
match prompt_user_for_role(&client, &mut stream) {
|
||||||
@ -139,9 +140,9 @@ fn setupctrlc() -> Arc<AtomicBool> {
|
|||||||
running
|
running
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Arc<Mutex<String>>> {
|
fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Receiver<String>> {
|
||||||
let buf = Arc::new(Mutex::new(String::new()));
|
let buf = Arc::new(Mutex::new(String::new()));
|
||||||
let buf2 = buf.clone();
|
let (sender, receiver) = channel();
|
||||||
let thread_stream = stream.try_clone()?;
|
let thread_stream = stream.try_clone()?;
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
@ -149,17 +150,10 @@ fn setup_server_message_recv(stream: &UnixStream) -> io::Result<Arc<Mutex<String
|
|||||||
//wait for server message
|
//wait for server message
|
||||||
let buffer =
|
let buffer =
|
||||||
clichess::read_line_from_stream(&thread_stream).expect("Error message from server");
|
clichess::read_line_from_stream(&thread_stream).expect("Error message from server");
|
||||||
{
|
sender.send(buffer).unwrap();
|
||||||
let mut server_message = buf2.lock().unwrap();
|
|
||||||
if server_message.is_empty() {
|
|
||||||
*server_message = buffer;
|
|
||||||
} else {
|
|
||||||
println!("Warning: server tried to send a message while the current one has not been computed yet.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Ok(buf)
|
Ok(receiver)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_user_input(client: &Client) -> String {
|
fn read_user_input(client: &Client) -> String {
|
||||||
@ -203,13 +197,14 @@ fn fetch_message_from_server(client: &Client) -> String {
|
|||||||
while client.running.load(Ordering::SeqCst) {
|
while client.running.load(Ordering::SeqCst) {
|
||||||
thread::sleep(time::Duration::from_millis(10));
|
thread::sleep(time::Duration::from_millis(10));
|
||||||
{
|
{
|
||||||
let mut server_response = client.server_message.lock().unwrap();
|
let server_response_recv = &client.server_message_recv;
|
||||||
if server_response.is_empty() {
|
match server_response_recv.try_recv() {
|
||||||
continue;
|
Ok(msg) => {
|
||||||
} else {
|
response = msg;
|
||||||
response = server_response.clone();
|
break;
|
||||||
server_response.clear();
|
}
|
||||||
break;
|
Err(TryRecvError::Disconnected) => println!("Error: server disconnected."),
|
||||||
|
Err(TryRecvError::Empty) => continue,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user