|
|
@@ -0,0 +1,65 @@
|
|
|
+use actix_web::{HttpRequest, HttpResponse, web, get};
|
|
|
+use serde_json::json;
|
|
|
+use tokio::sync::mpsc;
|
|
|
+use uuid::Uuid;
|
|
|
+use crate::{
|
|
|
+ users::User,
|
|
|
+ ws_registry::ClientRegistry
|
|
|
+};
|
|
|
+use std::sync::Mutex;
|
|
|
+
|
|
|
+#[get("/ws")]
|
|
|
+pub async fn route(
|
|
|
+ req: HttpRequest,
|
|
|
+ body: web::Payload,
|
|
|
+ users: web::Data<Mutex<Vec<User>>>,
|
|
|
+ registry: web::Data<ClientRegistry>
|
|
|
+) -> HttpResponse {
|
|
|
+ let cookie = match req.cookie("user") {
|
|
|
+ Some(c) => c,
|
|
|
+ None => { return HttpResponse::Unauthorized().json(json!({"msg": "Unauthorized"})) }
|
|
|
+ };
|
|
|
+ let user_id = match Uuid::parse_str(&cookie.value()) {
|
|
|
+ Ok(id) => id,
|
|
|
+ Err(_) => return HttpResponse::InternalServerError().finish()
|
|
|
+ };
|
|
|
+ let user = match users.lock() {
|
|
|
+ Ok(us) => match us.iter().find(|u| u.id == user_id).cloned() {
|
|
|
+ Some(a) => a,
|
|
|
+ None => { return HttpResponse::Unauthorized().json(json!({"msg": "Unauthorized"})) }
|
|
|
+ },
|
|
|
+ Err(_) => { return HttpResponse::InternalServerError().finish()}
|
|
|
+ };
|
|
|
+
|
|
|
+ let (response, mut session, mut msg_stream) = match actix_ws::handle(&req, body) {
|
|
|
+ Ok(a) => a,
|
|
|
+ Err(e) => { return HttpResponse::InternalServerError().json(json!({"msg": e.to_string()}))}
|
|
|
+ };
|
|
|
+
|
|
|
+ let (tx, mut rx) = mpsc::unbounded_channel::<String>();
|
|
|
+ let client_id = registry.register(tx, user.id);
|
|
|
+
|
|
|
+ let mut push_session = session.clone();
|
|
|
+ actix_web::rt::spawn(async move {
|
|
|
+ while let Some(payload) = rx.recv().await {
|
|
|
+ if push_session.text(payload).await.is_err() {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ let registry = registry.clone();
|
|
|
+ actix_web::rt::spawn(async move {
|
|
|
+ use futures_util::StreamExt;
|
|
|
+
|
|
|
+ while let Some(Ok(msg)) = msg_stream.next().await {
|
|
|
+ if let actix_ws::Message::Text(text) = msg {
|
|
|
+ let _ = session.text(text).await;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ registry.unregister(&client_id);
|
|
|
+ });
|
|
|
+
|
|
|
+ response
|
|
|
+}
|