diff --git a/src/main.rs b/src/main.rs index 8f50a85..257a468 100644 --- a/src/main.rs +++ b/src/main.rs @@ -66,7 +66,7 @@ async fn main() -> std::io::Result<()> { let mut redirect = None; let port_x = config.port_x.clone(); let port = config.port.clone(); - if ssl_builder.is_some() { + if ssl_builder.is_some() && config.port_x != "" { redirect = Some(HttpServer::new(move || { App::new() .wrap( @@ -99,16 +99,13 @@ async fn main() -> std::io::Result<()> { .service(fs::Files::new("/", &static_path).index_file("index.html")) }); - match ssl_builder { - Some(b) => { - let srv = server.bind_openssl(format!("{}:{}", config.bind_address, config.port), b)?.run(); - tokio::try_join!(redirect.unwrap(), srv)?; - }, - None => { - server.bind(format!("{}:{}", config.bind_address, config.port))?.run().await?; - } + if ssl_builder.is_some() && config.port_x != "" { + let srv = server.bind_openssl(format!("{}:{}", config.bind_address, config.port), ssl_builder.unwrap())?.run(); + tokio::try_join!(redirect.unwrap(), srv)?; + } else { + server.bind(format!("{}:{}", config.bind_address, config.port))?.run().await?; } - + Ok(()) } diff --git a/src/ws_sansad/mod.rs b/src/ws_sansad/mod.rs index bf7b3bb..0df29e1 100644 --- a/src/ws_sansad/mod.rs +++ b/src/ws_sansad/mod.rs @@ -34,11 +34,17 @@ const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5); /// How long before lack of client response causes a timeout const CLIENT_TIMEOUT: Duration = Duration::from_secs(15); +/// How often heartbeat pings are sent +const SPECIAL_HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5 * 60); +/// How long before lack of client response causes a timeout +const SPECIAL_CLIENT_TIMEOUT: Duration = Duration::from_secs(15 * 60); + pub struct WsSansad { kunjika: String, isthiti: Isthiti, addr: Option>, - hb: Instant + hb: Instant, + special_hb: Instant, } #[derive(Debug)] @@ -55,6 +61,7 @@ impl Actor for WsSansad { fn started(&mut self, ctx: &mut Self::Context) { self.addr = Some(ctx.address().clone()); // own addr self.hb(ctx); + self.special_hb(ctx); } fn stopping(&mut self, _: &mut Self::Context) -> Running { @@ -75,6 +82,7 @@ impl StreamHandler> for WsSansad { }, Ok(ws::Message::Pong(_)) => { self.hb = Instant::now(); }, Ok(ws::Message::Text(msg)) => { + self.special_hb = Instant::now(); tokio::runtime::Runtime::new().unwrap() .block_on(self.parse_text_handle(msg)); }, Ok(ws::Message::Close(msg)) => { @@ -93,7 +101,8 @@ impl WsSansad { kunjika: String::new(), isthiti: Isthiti::None, addr: None, - hb: Instant::now() + hb: Instant::now(), + special_hb: Instant::now() } } @@ -118,6 +127,25 @@ impl WsSansad { }); } + /// helper method that sends ping to client every second. + /// + /// also this method checks heartbeats from client + fn special_hb(&self, ctx: &mut ::Context) { + ctx.run_interval(SPECIAL_HEARTBEAT_INTERVAL, |act, ctx| { + // check client heartbeats + if Instant::now().duration_since(act.special_hb) > SPECIAL_CLIENT_TIMEOUT { + // heartbeat timed out + + // stop actor + tokio::runtime::Runtime::new().unwrap() + .block_on(act.leave_kaksh()); + ctx.stop(); + // don't try to send a ping + return; + } + }); + } + /// parse the request text from client async fn parse_text_handle(&mut self, msg: String) { if let Ok(val) = serde_json::from_str::(&msg) { diff --git a/static/js/app.js b/static/js/app.js index 865602d..e5710ab 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -44,6 +44,15 @@ socket.onerror = function(event) { 'page and if still don\'t work upgrade Web Browser'); } +socket.onclose = function (e) { + if(actions.has_key('leave')) return; + actions.clear(); + myinfo.kunjika = ''; + myinfo.name = ''; + State.login(); + State.hideProgress(); +} + // Listen for messages socket.onmessage = function(event) { var j = JSON.parse(event.data); diff --git a/static/js/onload.js b/static/js/onload.js index 30fe433..9817072 100644 --- a/static/js/onload.js +++ b/static/js/onload.js @@ -1,4 +1,4 @@ -if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches || getCookie('theme') == 'dark') { +if (getCookie('theme') == 'dark' || window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { $('body').toggleClass('dark'); }