feat: rename module to soulseek-rs
This commit is contained in:
+171
-73
@@ -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...");
|
||||
|
||||
Reference in New Issue
Block a user