feat: add missing message handlers

This commit is contained in:
michel
2024-09-13 20:58:04 +02:00
committed by Michel de Graaf
parent 6281b0c89e
commit 10f4a34ae4
34 changed files with 1889 additions and 564 deletions
+135 -12
View File
@@ -1,36 +1,159 @@
use crate::server::{Server, ServerAddress};
use crate::{
peer::{default_peer::DefaultPeer, peer::Peer},
server::{PeerAddress, Server},
utils::md5,
};
use std::{
collections::HashMap,
sync::{
mpsc::{Receiver, Sender},
Mutex,
},
thread,
};
use std::{
sync::{mpsc, Arc},
time::{Duration, Instant},
};
pub enum ClientOperation {
ConnectToPeer(Peer),
}
struct ClientContext {
peers: HashMap<String, DefaultPeer>,
sender: Option<Sender<ClientOperation>>,
}
impl ClientContext {
pub fn new() -> Self {
Self {
peers: HashMap::new(),
sender: None,
}
}
}
pub struct Client {
address: ServerAddress,
address: PeerAddress,
username: String,
password: String,
server: Option<Server>,
context: Arc<Mutex<ClientContext>>,
}
impl Client {
pub fn new(address: ServerAddress, username: String, password: String) -> Self {
pub fn new(address: PeerAddress, username: String, password: String) -> Self {
Self {
address,
username,
password,
server: None,
context: Arc::new(Mutex::new(ClientContext::new())),
}
}
pub fn connect(&self) {
match Server::new(self.address.clone()) {
Ok(mut server) => {
pub fn connect(&mut self) {
let (sender, message_reader): (Sender<ClientOperation>, Receiver<ClientOperation>) =
mpsc::channel();
self.context.lock().unwrap().sender = Some(sender.clone());
// self.read_form_channel(message_reader);
self.server = match Server::new(self.address.clone(), sender) {
Ok(server) => {
println!(
"Connected to server at {}:{}",
server.get_address().get_host(),
server.get_address().get_port()
);
// Attempt to login
println!("Logging in as {}", self.username);
if let Err(e) = server.login(&self.username, &self.password) {
eprintln!("Error during login: {}", e);
Self::listen_to_client_operations(message_reader, self.context.clone());
Some(server)
}
Err(e) => {
eprintln!("Error connecting to server: {}", e);
None
}
};
}
pub fn login(&self) -> Result<bool, std::io::Error> {
// Attempt to login
println!("Logging in as {}", self.username);
if let Some(server) = &self.server {
let result = server.login(&self.username, &self.password);
if result.unwrap() == true {
return Ok(true);
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Error logging in",
));
}
} else {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"Not connected to server",
));
}
}
pub fn search(&self, query: &str, timeout: Duration) {
println!("Searching for {}", query);
if let Some(server) = &self.server {
let hash = md5::md5(query);
let token = i32::from_str_radix(&hash[0..8].to_string(), 16).unwrap();
server.file_search(token, &query);
} else {
eprintln!("Not connected to server");
}
let start = Instant::now();
loop {
if start.elapsed() >= timeout {
break;
}
}
if let Some(server) = &self.server {
println!("server {:?}", server)
}
}
fn listen_to_client_operations(
reader: Receiver<ClientOperation>,
client_context: Arc<Mutex<ClientContext>>,
) {
thread::spawn(move || loop {
if let Ok(operation) = reader.recv() {
match operation {
ClientOperation::ConnectToPeer(peer) => {
Self::connect_to_peer(peer, client_context.clone())
}
}
}
Err(e) => eprintln!("Error connecting to server: {}", e),
});
}
fn connect_to_peer(peer: Peer, client_context: Arc<Mutex<ClientContext>>) {
let context = client_context.clone();
let unlocked_context = context.lock().unwrap();
if let Some(sender) = &unlocked_context.sender {
if unlocked_context.peers.get(&peer.username).is_none() {
let peer_clone = peer.clone();
let sender_clone = sender.clone();
thread::spawn(move || {
let default_peer = DefaultPeer::new(peer_clone, sender_clone);
match default_peer.connect() {
Ok(p) => {
let mut context = client_context.lock().unwrap();
context.peers.insert(peer.username, p);
}
Err(_e) => {
// eprintln!("Error connecting to peer: {:?}", e)
}
}
});
}
} else {
eprintln!("No sender found");
}
}
}