restart listener when config changes

This commit is contained in:
2023-04-28 14:33:04 -07:00
parent 33a5600a30
commit 70d71ce14e
6 changed files with 171 additions and 74 deletions

View File

@ -1,12 +1,22 @@
use core::time::Duration;
use std::io;
use std::net::{SocketAddr, SocketAddrV4};
use tokio::net::{TcpListener, TcpStream};
use std::net::{
Ipv4Addr,
SocketAddr,
SocketAddrV4,
TcpListener as StdTcpListener,
};
use tokio::net::{
TcpListener,
TcpStream,
};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::sync::oneshot;
use tokio::time::sleep;
use tauri::{AppHandle, Manager};
use tauri::async_runtime as rt;
use tauri::async_runtime::JoinHandle;
use crate::{clientinfo, clientinfo::Client};
use crate::errors::*;
@ -159,17 +169,55 @@ impl Handler {
}
pub async fn serve(addr: SocketAddrV4, app_handle: AppHandle) -> io::Result<()> {
let listener = TcpListener::bind(&addr).await?;
println!("Listening on {addr}");
loop {
match listener.accept().await {
Ok((stream, _)) => {
let handler = Handler::new(stream, app_handle.app_handle());
tauri::async_runtime::spawn(handler.handle());
},
Err(e) => {
eprintln!("Error accepting connection: {e}");
#[derive(Debug)]
pub struct Server {
addr: Ipv4Addr,
port: u16,
app_handle: AppHandle,
task: JoinHandle<()>,
}
impl Server {
pub async fn new(addr: Ipv4Addr, port: u16, app_handle: AppHandle) -> io::Result<Server> {
// construct the listener before passing it to the task so that we know if it fails
let sock_addr = SocketAddrV4::new(addr, port);
let listener = TcpListener::bind(&sock_addr).await?;
let task = rt::spawn(Self::serve(listener, app_handle.app_handle()));
Ok(Server { addr, port, app_handle, task})
}
// this is blocking because it's too much of a paint to juggle mutexes otherwise
pub fn rebind(&mut self, addr: Ipv4Addr, port: u16) -> io::Result<()> {
if addr == self.addr && port == self.port {
return Ok(())
}
let sock_addr = SocketAddrV4::new(addr, port);
let std_listener = StdTcpListener::bind(&sock_addr)?;
std_listener.set_nonblocking(true)?;
let async_listener = TcpListener::from_std(std_listener)?;
let new_task = rt::spawn(Self::serve(async_listener, self.app_handle.app_handle()));
self.task.abort();
self.addr = addr;
self.port = port;
self.task = new_task;
Ok(())
}
async fn serve(listener: TcpListener, app_handle: AppHandle) {
loop {
match listener.accept().await {
Ok((stream, _)) => {
let handler = Handler::new(stream, app_handle.app_handle());
rt::spawn(handler.handle());
},
Err(e) => {
eprintln!("Error accepting connection: {e}");
}
}
}
}