Add WIP controller websocket

This commit is contained in:
Tobias Reisinger 2023-11-22 16:28:46 +01:00
parent ee5d4e2126
commit 131bdeec78
6 changed files with 124 additions and 0 deletions

66
Cargo.lock generated
View file

@ -2,6 +2,31 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "actix"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cba56612922b907719d4a01cf11c8d5b458e7d3dba946d0435f20f58d6795ed2"
dependencies = [
"actix-macros",
"actix-rt",
"actix_derive",
"bitflags 2.4.1",
"bytes",
"crossbeam-channel",
"futures-core",
"futures-sink",
"futures-task",
"futures-util",
"log",
"once_cell",
"parking_lot",
"pin-project-lite",
"smallvec",
"tokio",
"tokio-util",
]
[[package]]
name = "actix-codec"
version = "0.5.1"
@ -169,6 +194,24 @@ dependencies = [
"url",
]
[[package]]
name = "actix-web-actors"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf6e9ccc371cfddbed7aa842256a4abc7a6dcac9f3fce392fe1d0f68cfd136b2"
dependencies = [
"actix",
"actix-codec",
"actix-http",
"actix-web",
"bytes",
"bytestring",
"futures-core",
"pin-project-lite",
"tokio",
"tokio-util",
]
[[package]]
name = "actix-web-codegen"
version = "4.2.2"
@ -181,6 +224,17 @@ dependencies = [
"syn 2.0.38",
]
[[package]]
name = "actix_derive"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
]
[[package]]
name = "addr2line"
version = "0.21.0"
@ -675,6 +729,16 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200"
dependencies = [
"cfg-if",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-queue"
version = "0.3.8"
@ -780,7 +844,9 @@ dependencies = [
name = "emgauwa-core"
version = "0.1.0"
dependencies = [
"actix",
"actix-web",
"actix-web-actors",
"chrono",
"config",
"dotenv",

View file

@ -5,7 +5,9 @@ edition = "2018"
authors = ["Tobias Reisinger <tobias@msrg.cc>"]
[dependencies]
actix = "0.13"
actix-web = "4.4"
actix-web-actors = "4.2"
sqlx = { version = "0.7", features = ["sqlite", "runtime-async-std", "macros", "chrono"] }

View file

@ -1 +1,2 @@
pub mod schedules;
pub mod ws;

View file

@ -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<Sqlite>,
}
impl Actor for ControllerWs {
type Context = ws::WebsocketContext<Self>;
}
async fn get_schedules(pool: &mut Pool<Sqlite>) -> Result<Vec<Schedule>, ApiError> {
let mut pool_conn = pool.acquire().await?;
Ok(Schedule::get_all(&mut pool_conn).await?)
}
/// Handler for ws::Message message
impl StreamHandler<Result<Message, ProtocolError>> for ControllerWs {
fn handle(&mut self, msg: Result<Message, ProtocolError>, 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<Pool<Sqlite>>,
req: HttpRequest,
stream: web::Payload,
) -> Result<HttpResponse, ApiError> {
let resp = ws::start(
ControllerWs {
pool: pool.get_ref().clone(),
},
&req,
stream,
)
.map_err(|_| ApiError::InternalError(String::from("error starting websocket")));
println!("{:?}", resp);
resp
}

View file

@ -0,0 +1 @@
pub mod controllers;

View file

@ -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()