feat: rename module to soulseek-rs

This commit is contained in:
Michel de Graaf
2025-07-31 22:24:34 +02:00
parent 5aa4472510
commit cd3dca40c5
27 changed files with 1072 additions and 359 deletions
+171 -73
View File
@@ -1,11 +1,12 @@
use crate::dispatcher::MessageDispatcher;
use crate::message::peer::FileSearchResponse;
use crate::message::peer::{
GetShareFileList, TransferRequest, UploadFailedHandler,
GetShareFileList, PlaceInQueueResponse, TransferRequest, TransferResponse,
UploadFailedHandler,
};
use crate::message::server::MessageFactory;
use crate::message::{Handlers, Message, MessageReader, MessageType};
use crate::types::{FileSearchResult, Transfer};
use crate::types::{Download, FileSearchResult, Transfer};
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender};
@@ -20,6 +21,7 @@ use std::net::ToSocketAddrs;
use std::time::Duration;
#[allow(dead_code)]
#[derive(Debug)]
pub struct DefaultPeer {
peer: Peer,
peer_channel: Option<Sender<PeerOperation>>,
@@ -33,6 +35,15 @@ pub enum PeerOperation {
SendMessage(Message),
FileSearchResult(FileSearchResult),
TransferRequest(Transfer),
TransferResponse {
token: u32,
allowed: bool,
reason: Option<String>,
},
PlaceInQueueResponse {
filename: String,
place: u32,
},
}
impl DefaultPeer {
pub fn new(peer: Peer, client_channel: Sender<ClientOperation>) -> Self {
@@ -44,7 +55,43 @@ impl DefaultPeer {
write_thread: None,
}
}
pub fn disconnect(mut self) {
debug!("[default_peer:{}] disconnect", self.peer.username.clone());
if let Err(e) = self.client_channel.send(
ClientOperation::PeerDisconnected(self.peer.username.clone()),
) {
error!("Failed to send disconnect notification: {}", e);
}
self.peer_channel.take();
}
pub fn connect_with_socket(
mut self,
mut stream: TcpStream,
) -> Result<Self, io::Error> {
if let Some(token) = self.peer.token {
let mut message: Vec<u8> = [0, 5, 0, 0, 0, 0].to_vec();
message.extend_from_slice(&token.to_le_bytes());
stream.write_all(&message).unwrap();
}
stream.set_read_timeout(Some(Duration::from_secs(5)))?;
stream.set_write_timeout(Some(Duration::from_secs(5)))?;
trace!(
"[default_peer:{}] connect_with_socket: direct",
self.peer.username
);
self.start_read_write_loops(stream)?;
Ok(self)
}
pub fn connect(mut self) -> Result<Self, io::Error> {
println!(
"[default_peer] Connecting to {} on port {}",
self.peer.host, self.peer.port
);
let socket_address = format!("{}:{}", self.peer.host, self.peer.port)
.to_socket_addrs()?
.next()
@@ -52,6 +99,7 @@ impl DefaultPeer {
io::Error::new(io::ErrorKind::InvalidInput, "Invalid address")
})?;
trace!("[default_peer:{}] connect: indirect", self.peer.username);
let mut stream = TcpStream::connect_timeout(
&socket_address,
Duration::from_secs(20),
@@ -74,6 +122,10 @@ impl DefaultPeer {
&mut self,
stream: TcpStream,
) -> Result<(), io::Error> {
debug!(
"[default_peer:{}] start_read_write_loops",
self.peer.username
);
let (peer_sender, peer_reader): (
Sender<PeerOperation>,
Receiver<PeerOperation>,
@@ -86,17 +138,23 @@ impl DefaultPeer {
let mut write_stream = stream; // Use the original stream for writing
let peer = self.peer.clone();
let peer_clone = self.peer.clone();
let client_channel_for_read = self.client_channel.clone();
// Spawn the reader thread
self.read_thread = Some(thread::spawn(move || {
let mut handlers = Handlers::new();
handlers.register_handler(FileSearchResponse);
handlers.register_handler(TransferRequest);
handlers.register_handler(TransferResponse);
handlers.register_handler(GetShareFileList);
handlers.register_handler(UploadFailedHandler);
handlers.register_handler(PlaceInQueueResponse);
let dispatcher = MessageDispatcher::new(peer_sender, handlers);
let dispatcher = MessageDispatcher::new(
"default_peer".to_string(),
peer_sender,
handlers,
);
let mut buffered_reader = MessageReader::new();
loop {
@@ -113,7 +171,7 @@ impl DefaultPeer {
continue;
}
Err(e) => {
error!("Error reading from peer: {}. Terminating read loop.", e);
error!("[default_peer:{}] Error reading from peer: {}. Terminating read loop.",peer.username, e);
let _ = client_channel_for_read.send(
ClientOperation::PeerDisconnected(
peer.username.clone(),
@@ -147,6 +205,7 @@ impl DefaultPeer {
peer.username.clone(),
),
);
break;
}
Ok(None) => continue,
@@ -158,77 +217,109 @@ impl DefaultPeer {
let peer_channel = self.peer_channel.clone();
let peer_username = self.peer.username.clone();
self.write_thread = Some(thread::spawn(move || {
loop {
match peer_reader.recv() {
Ok(operation) => {
match operation {
PeerOperation::SendMessage(message) => {
trace!(
"[default_peer:{:?}] ➡ {:?} - {:?}",
peer_username,
message
.get_message_name(
MessageType::Peer,
u32::from_le_bytes(
message
.get_slice(0, 4)
.try_into()
.unwrap()
)
)
.map_err(|e| e.to_string()),
message
);
self.write_thread = Some(thread::spawn(move || loop {
match peer_reader.recv() {
Ok(operation) => match operation {
PeerOperation::SendMessage(message) => {
trace!(
"[default_peer:{:?}] ➡ {:?} - {:?}",
peer_username,
message
.get_message_name(
MessageType::Peer,
u32::from_le_bytes(
message
.get_slice(0, 4)
.try_into()
.unwrap()
)
)
.map_err(|e| e.to_string()),
message
);
if let Err(e) = write_stream
.write_all(&message.get_buffer())
{
error!("Error writing message to stream: {} - {}. Terminating write loop.", peer_username, e);
let _ = client_channel.send(
ClientOperation::PeerDisconnected(
peer_username.clone(),
),
);
break;
}
}
PeerOperation::FileSearchResult(file_search) => {
client_channel
.send(ClientOperation::SearchResult(
file_search,
))
.unwrap();
}
PeerOperation::TransferRequest(transfer) => {
debug!(
"[default_peer:{}] transfer request: {:?}",
peer_username, transfer
);
client_channel
.send(ClientOperation::TransferRequest(
transfer.clone(),
))
.unwrap();
let transfer_response =
MessageFactory::build_transfer_response_message(transfer.clone());
if let Some(sender) = peer_channel.clone() {
sender
.send(PeerOperation::SendMessage(
transfer_response,
))
.unwrap();
}
}
if let Err(e) =
write_stream.write_all(&message.get_buffer())
{
error!("Error writing message to stream: {} - {}. Terminating write loop.", peer_username, e);
let _ = client_channel.send(
ClientOperation::PeerDisconnected(
peer_username.clone(),
),
);
break;
}
}
Err(_) => {
// The sender has been dropped, the peer is shutting down.
debug!("Peer channel closed. Terminating write loop.");
PeerOperation::FileSearchResult(file_search) => {
client_channel
.send(ClientOperation::SearchResult(file_search))
.unwrap();
}
PeerOperation::TransferRequest(transfer) => {
debug!(
"[default_peer:{:}] TransferRequest for {}",
peer_username, transfer.token
);
let transfer_response =
MessageFactory::build_transfer_response_message(
transfer.clone(),
);
if let Some(sender) = peer_channel.clone() {
sender
.send(PeerOperation::SendMessage(
transfer_response,
))
.unwrap();
}
debug!(
"[default_peer:{:}] TransferResponse for {}",
peer_username, transfer.token
);
break;
}
PeerOperation::TransferResponse {
token,
allowed,
reason,
} => {
debug!(
"[default_peer:{}] transfer response token: {} allowed: {}",
peer_username, token, allowed
);
if !allowed {
if let Some(reason_text) = reason {
debug!(
"[default_peer:{}] Transfer rejected: {} - token {}, I will receive TransferRequest soon...",
peer_username.clone(),
reason_text,
token
);
}
} else {
debug!("[default_peer:{:}] Transfer allowed, ready to connect with token {:}",peer_username, token);
client_channel
.send(ClientOperation::DownloadFromPeer(
token,
peer_clone.clone(),
))
.unwrap();
}
}
PeerOperation::PlaceInQueueResponse { filename, place } => {
debug!(
"[default_peer:{}] Place in queue response - file: {}, place: {}",
peer_username, filename, place
);
}
},
Err(_) => {
debug!("[default_peer:{}] Peer channel closed. Terminating write loop.", peer_username);
break;
}
}
}));
@@ -236,8 +327,14 @@ impl DefaultPeer {
Ok(())
}
pub fn transfer_request(&self, filename: String) -> Result<(), io::Error> {
let message = MessageFactory::build_queue_upload_message(&filename);
pub fn transfer_request(
&self,
download: Download,
) -> Result<(), io::Error> {
let message = MessageFactory::build_transfer_request_message(
&download.filename,
download.token,
);
if let Some(sender) = &self.peer_channel {
sender.send(PeerOperation::SendMessage(message)).unwrap();
}
@@ -248,6 +345,7 @@ impl DefaultPeer {
impl Drop for DefaultPeer {
fn drop(&mut self) {
self.peer_channel = None;
trace!("[default_peer:{}] drop", self.peer.username);
if let Some(handle) = self.read_thread.take() {
debug!("Joining read thread...");