From eb3271773a8aa21aa29f36e65e167d8c76d8ca1a Mon Sep 17 00:00:00 2001 From: Jovi Hsu Date: Wed, 3 Nov 2021 16:32:16 +0800 Subject: [PATCH] simple websocket --- backend/Cargo.toml | 7 +++++++ backend/src/main.rs | 38 +++++++++++++++++++++++++++----------- backend/src/ws.rs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 backend/src/ws.rs diff --git a/backend/Cargo.toml b/backend/Cargo.toml index df9f748..fccd9d2 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -15,10 +15,17 @@ repository = "https://www.github.com/HsuJv/webgateway" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +actix = "0.10.0" actix-web = "3.3.2" actix-files = "0.5.0" tokio-tar = "0.3.0" urlencoding = "2.1.0" +actix-web-actors = "3.0.0" + +# log systems +femme = "1.3" +log = "0.4" +async-log = "2.0.0" [profile.dev] panic = "unwind" diff --git a/backend/src/main.rs b/backend/src/main.rs index 1a3e8a9..f27ffdf 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -1,31 +1,46 @@ use actix_files as fs; -use actix_web::http::StatusCode; +use actix_web::http::{ContentEncoding, StatusCode}; use actix_web::*; -const STATIC_DIR: &str = "./static/"; -// #[get("/{id}/{name}/index.html")] -// async fn index(web::Path((id, name)): web::Path<(u32, String)>) -> impl Responder { -// format!("Hello {}! id:{}", name, id) -// } +use femme; +use log::info; +mod ws; + +const STATIC_DIR: &str = "./static/"; +const PAGE_INDEX: &str = "./static/index.html"; +const PAGE_NOT_FOUND: &str = "./static/p404.html"; + +fn setup_logger() { + let logger = femme::pretty::Logger::new(); + async_log::Logger::wrap(logger, || 12) + .start(log::LevelFilter::Trace) + .unwrap(); +} + +#[get("/")] async fn index(_: HttpRequest) -> Result { - Ok(fs::NamedFile::open(format!("{}/index.html", STATIC_DIR))?) + Ok(fs::NamedFile::open(PAGE_INDEX)?) } async fn p404() -> Result { - Ok(fs::NamedFile::open(format!("{}/p404.html", STATIC_DIR))? - .set_status_code(StatusCode::NOT_FOUND)) + Ok(fs::NamedFile::open(PAGE_NOT_FOUND)?.set_status_code(StatusCode::NOT_FOUND)) } #[actix_web::main] async fn main() -> std::io::Result<()> { + setup_logger(); + + info!("Server starts at http://127.0.0.1:8080"); HttpServer::new(move || { App::new() - .service(web::resource("/").route(web::get().to(index))) + .wrap(middleware::Compress::new(ContentEncoding::Gzip)) + .service(index) + .service(web::resource("/ws").route(web::get().to(ws::index))) .service( fs::Files::new("/static", STATIC_DIR) .prefer_utf8(true) - .index_file(format!("{}/index.html", STATIC_DIR)) + .index_file(PAGE_INDEX) .use_etag(true) .default_handler(web::route().to(p404)), ) @@ -34,5 +49,6 @@ async fn main() -> std::io::Result<()> { .bind("127.0.0.1:8080")? .run() .await?; + Ok(()) } diff --git a/backend/src/ws.rs b/backend/src/ws.rs new file mode 100644 index 0000000..b4367c3 --- /dev/null +++ b/backend/src/ws.rs @@ -0,0 +1,32 @@ +use actix::{Actor, StreamHandler}; +use actix_web::{web, Error, HttpRequest, HttpResponse}; +use actix_web_actors::ws; +use log::*; + +/// Define HTTP actor +struct MyWs; + +impl Actor for MyWs { + type Context = ws::WebsocketContext; +} + +/// Handler for ws::Message message +impl StreamHandler> for MyWs { + fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { + match msg { + Ok(ws::Message::Ping(msg)) => ctx.pong(&msg), + Ok(ws::Message::Text(text)) => ctx.text(text), + Ok(ws::Message::Binary(bin)) => ctx.binary(bin), + _ => (), + } + } +} + +pub async fn index(req: HttpRequest, stream: web::Payload) -> Result { + let resp = ws::start(MyWs {}, &req, stream); + match &resp { + Ok(resp) => info!("{:?}", resp), + Err(e) => error!("{:?}", e), + } + resp +}