I need to commit more often. First commit BTW
This commit is contained in:
16
lib/Cargo.toml
Normal file
16
lib/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "lib"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0"
|
||||
log = "0.4"
|
||||
|
||||
crossbeam = "0.8"
|
||||
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
rmp-serde = "1.1"
|
||||
140
lib/src/lib.rs
Normal file
140
lib/src/lib.rs
Normal file
@@ -0,0 +1,140 @@
|
||||
use std::{
|
||||
io::{self, Read, Write},
|
||||
net::{TcpListener, TcpStream},
|
||||
result::Result::Ok,
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use anyhow::Result;
|
||||
use crossbeam::channel::{self, Receiver, Sender};
|
||||
use log::{error, info};
|
||||
use rmp_serde::{Deserializer, Serializer};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub fn create_listener(address: &str, port: u16) -> TcpListener {
|
||||
TcpListener::bind((address, port)).unwrap_or_else(|e| {
|
||||
if e.kind() == io::ErrorKind::AddrInUse {
|
||||
info!("Port {} is already being used by another program", port);
|
||||
std::process::exit(1);
|
||||
} else if e.kind() == io::ErrorKind::AddrNotAvailable {
|
||||
info!("Address {} not available", address);
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
panic!("{:?}", e);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum ClientMessage {
|
||||
Next,
|
||||
Previous,
|
||||
PlayPause,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub enum ServerMessage {
|
||||
NowPlaying(String),
|
||||
}
|
||||
|
||||
pub fn start_server() -> Result<(Sender<ServerMessage>, Receiver<ClientMessage>)> {
|
||||
let (sender_c, reciever_c) = channel::bounded(4);
|
||||
let (sender_s, reciever_s) = channel::bounded(4);
|
||||
|
||||
let server = create_listener("0.0.0.0", 6487);
|
||||
info!("Listening on port {}", 6487);
|
||||
server.set_nonblocking(true)?;
|
||||
|
||||
thread::spawn(move || {
|
||||
for stream_result in server.incoming() {
|
||||
match stream_result {
|
||||
Ok(stream) => {
|
||||
let reciever_s = reciever_s.clone();
|
||||
let sender_c = sender_c.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
if let Err(error) = handle_connection(stream, reciever_s, sender_c,"Client") {
|
||||
error!("error while handling stream: {}", error);
|
||||
}
|
||||
})
|
||||
} // Spawn a new thread, ignore the return value because we don't need to join threads
|
||||
_ => continue,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
Ok((sender_s, reciever_c))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
pub fn start_client() -> Result<(Sender<ClientMessage>, Receiver<ServerMessage>)> {
|
||||
let (sender_c, reciever_c) = channel::bounded(4);
|
||||
let (sender_s, reciever_s) = channel::bounded(4);
|
||||
|
||||
info!("Connecting");
|
||||
let server = TcpStream::connect("127.0.0.1:6487")?;
|
||||
info!("Connected successfully to {}", "127.0.0.1:6487");
|
||||
server.set_nonblocking(true)?;
|
||||
|
||||
thread::spawn(move || {
|
||||
handle_connection(server, reciever_c, sender_s, "Server") });
|
||||
|
||||
Ok((sender_c, reciever_s))
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fn handle_connection<R,S>(
|
||||
mut stream: TcpStream,
|
||||
reciever: Receiver<R>,
|
||||
sender: Sender<S>,
|
||||
origin: &str,
|
||||
) -> Result<()>
|
||||
where R : Serialize
|
||||
{
|
||||
loop {
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
if !reciever.is_empty() {
|
||||
let msg: R = reciever.recv()?;
|
||||
let mut msg_buf = Vec::new();
|
||||
msg.serialize(&mut Serializer::new(&mut msg_buf))?;
|
||||
|
||||
stream.write(&msg_buf)?;
|
||||
}
|
||||
handle_read(&mut stream, origin)?;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_read(stream: &mut TcpStream, origin: &str) -> Result<()> {
|
||||
let mut byte_read = 0;
|
||||
let mut read_buff = [0u8; 4096];
|
||||
|
||||
if byte_read == 0 {
|
||||
byte_read = match stream.read(&mut read_buff) {
|
||||
Ok(0) => return Ok(()), // Socket closed
|
||||
Ok(n) => n,
|
||||
Err(e) if e.kind() == io::ErrorKind::WouldBlock => 0, // If there is no data, return 0 bytes written
|
||||
Err(_) => return Ok(()),
|
||||
};
|
||||
}
|
||||
|
||||
// Write data from tunnel to stream
|
||||
if byte_read > 0 {
|
||||
info!("[{origin}] {:?}", &read_buff[0..byte_read]);
|
||||
|
||||
if origin == "Server" {
|
||||
let a: ServerMessage = rmp_serde::from_slice(&read_buff[0..byte_read]).unwrap();
|
||||
info!("{:?}", a);
|
||||
} else {
|
||||
let a: ClientMessage = rmp_serde::from_slice(&read_buff[0..byte_read]).unwrap();
|
||||
info!("{:?}", a);
|
||||
|
||||
}
|
||||
//sender_c.send(msg);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user