use crate::TallyState; use actix::prelude::*; use actix_web::{server, App, HttpResponse}; use futures::future::Future; use std::sync::mpsc; use std::thread; use typed_html::dom::DOMTree; use typed_html::html; fn build_template() -> DOMTree { html!( "OpenTally Control"

"OpenTally Control"

) } pub struct WebServer { addr: Addr, shutdown_rx: mpsc::Receiver<()>, } impl WebServer { pub fn run(addr: std::net::SocketAddr) -> WebServer { // todo: not have the damn js inline in the func const JS: &'static str = r#" var sock = new WebSocket("ws://" + window.location.host + "/ws"); sock.onmessage = function (e) { console.log(e); } sock.onopen = function (e) { sock.send("Hello!"); }"#; let (shutdown_tx, shutdown_rx) = mpsc::channel(); let (tx, rx) = mpsc::channel(); thread::spawn(move || { let sys = actix::System::new("test"); let addr = server::new(|| { App::new() .resource("/", |r| { r.f(|_r| { HttpResponse::Ok() .content_type("text/html") .body(build_template().to_string()) }) }) .resource("script.js", |r| { r.f(|_r| HttpResponse::Ok().content_type("text/javascript").body(JS)) }) //.resource("/ws", ) }) .bind(addr) .expect("Error binding to address.") .start(); tx.send(addr).unwrap(); sys.run(); shutdown_tx.send(()).unwrap(); // Notify that we have shutdown }); let addr = rx.recv().unwrap(); WebServer { addr: addr, shutdown_rx: shutdown_rx, } } pub fn shutdown(self) { log::debug!("Web server shutting down..."); self.addr .send(actix_web::server::StopServer { graceful: true }) .wait() .unwrap() .unwrap(); let _ = self.shutdown_rx.recv().unwrap(); // wait for webserver shutdown log::info!("Web server shutdown"); } }