diff --git a/Cargo.lock b/Cargo.lock index 769c3b5..5c6963e 100644 Binary files a/Cargo.lock and b/Cargo.lock differ diff --git a/Cargo.toml b/Cargo.toml index 3d3f9d6..a1f6586 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,9 @@ edition = "2018" authors = ["Tobias Reisinger "] [dependencies] +actix = "0.13" actix-web = "4.4" +actix-web-actors = "4.2" sqlx = { version = "0.7", features = ["sqlite", "runtime-async-std", "macros", "chrono"] } diff --git a/src/handlers/v1/mod.rs b/src/handlers/v1/mod.rs index 68f52e6..54b6498 100644 --- a/src/handlers/v1/mod.rs +++ b/src/handlers/v1/mod.rs @@ -1 +1,2 @@ pub mod schedules; +pub mod ws; diff --git a/src/handlers/v1/ws/controllers.rs b/src/handlers/v1/ws/controllers.rs new file mode 100644 index 0000000..d357195 --- /dev/null +++ b/src/handlers/v1/ws/controllers.rs @@ -0,0 +1,53 @@ +use crate::db::schedules::Schedule; +use crate::handlers::errors::ApiError; +use actix::{Actor, StreamHandler}; +use actix_web::{get, web, HttpRequest, HttpResponse}; +use actix_web_actors::ws; +use actix_web_actors::ws::ProtocolError; +use sqlx::{Pool, Sqlite}; +use ws::Message; + +struct ControllerWs { + pub pool: Pool, +} + +impl Actor for ControllerWs { + type Context = ws::WebsocketContext; +} + +async fn get_schedules(pool: &mut Pool) -> Result, ApiError> { + let mut pool_conn = pool.acquire().await?; + + Ok(Schedule::get_all(&mut pool_conn).await?) +} + +/// Handler for ws::Message message +impl StreamHandler> for ControllerWs { + fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { + let schedules = futures::executor::block_on(get_schedules(&mut self.pool)).unwrap(); + let schedules_json = serde_json::to_string(&schedules).unwrap(); + match msg { + Ok(Message::Ping(msg)) => ctx.pong(&msg), + Ok(Message::Text(_text)) => ctx.text(schedules_json), + _ => {} + } + } +} + +#[get("/api/v1/ws/controllers")] +pub async fn index( + pool: web::Data>, + req: HttpRequest, + stream: web::Payload, +) -> Result { + let resp = ws::start( + ControllerWs { + pool: pool.get_ref().clone(), + }, + &req, + stream, + ) + .map_err(|_| ApiError::InternalError(String::from("error starting websocket"))); + println!("{:?}", resp); + resp +} diff --git a/src/handlers/v1/ws/mod.rs b/src/handlers/v1/ws/mod.rs new file mode 100644 index 0000000..f916674 --- /dev/null +++ b/src/handlers/v1/ws/mod.rs @@ -0,0 +1 @@ +pub mod controllers; diff --git a/src/main.rs b/src/main.rs index 6f8ef7b..067ab86 100644 --- a/src/main.rs +++ b/src/main.rs @@ -47,6 +47,7 @@ async fn main() -> std::io::Result<()> { .service(handlers::v1::schedules::add_list) .service(handlers::v1::schedules::update) .service(handlers::v1::schedules::delete) + .service(handlers::v1::ws::controllers::index) }) .bind(format!("{}:{}", settings.host, settings.port))? .run()