2025-10-26 15:43:51 -04:00
|
|
|
use actix_web::{rt, web::{Payload, Data, Path, Json}, Error, HttpRequest, HttpResponse, get, post};
|
|
|
|
|
//use actix_ws::AggregatedMessage;
|
|
|
|
|
//use futures::StreamExt as _;
|
|
|
|
|
|
|
|
|
|
#[get("/intercom/.oj_services/{name}")]
|
|
|
|
|
pub async fn services_ws(req: HttpRequest, stream: Payload, auth: Data<super::IntercomAuth>, reg: Data<super::Users>, name: Path<String>) -> Result<HttpResponse, Error> {
|
2026-07-05 16:33:26 -04:00
|
|
|
auth.validate(&req, &format!(".oj_services/{}", urlencoding::encode(&name)))?;
|
2025-10-26 15:43:51 -04:00
|
|
|
let (res, mut session, _stream) = actix_ws::handle(&req, stream)?;
|
|
|
|
|
|
|
|
|
|
/*let mut stream = stream
|
|
|
|
|
.aggregate_continuations()
|
|
|
|
|
.max_continuation_size(2_usize.pow(20)); // aggregate continuation frames up to 1MiB
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
let (tx, mut rx) = tokio::sync::mpsc::channel(16);
|
2026-03-17 21:52:15 -04:00
|
|
|
reg.register_web_service(name.clone(), tx).await;
|
2025-10-26 15:43:51 -04:00
|
|
|
log::debug!("Registered web services intercom websocket for user {}", name);
|
|
|
|
|
|
|
|
|
|
// start task but don't wait for it
|
|
|
|
|
rt::spawn(async move {
|
2025-10-31 21:02:10 -04:00
|
|
|
let mut is_ok = false;
|
|
|
|
|
while let Some(op) = rx.recv().await {
|
|
|
|
|
match op {
|
|
|
|
|
super::IntercomOp::Message(msg) => {
|
|
|
|
|
if let Err(e) = session.text(serde_json::to_string(&msg).unwrap()).await {
|
|
|
|
|
log::warn!("Failed to send services intercom to user {}: {}", name, e);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
super::IntercomOp::Info(info) => {
|
|
|
|
|
match info {
|
|
|
|
|
super::IntercomInfo::Close => {
|
|
|
|
|
is_ok = true;
|
|
|
|
|
break;
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-10-26 15:43:51 -04:00
|
|
|
}
|
2025-10-31 21:02:10 -04:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if !is_ok {
|
2026-03-17 21:52:15 -04:00
|
|
|
reg.remove_web_service(name.clone()).await;
|
2025-10-26 15:43:51 -04:00
|
|
|
}
|
|
|
|
|
rx.close();
|
|
|
|
|
session.close(Some(actix_ws::CloseReason {
|
|
|
|
|
code: actix_ws::CloseCode::Normal,
|
|
|
|
|
description: Some("End of channel".to_owned()),
|
|
|
|
|
})).await.expect("Failed to close a services intercom websocket session");
|
|
|
|
|
log::debug!("Web services intercom websocket closed for {}", name);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// respond immediately with response connected to WS session
|
|
|
|
|
Ok(res)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[post("/intercom/.oj_services/{name}/messages")]
|
|
|
|
|
pub async fn service_msg(req: HttpRequest, body: Json<oj_rc_core::persist::user::intercom::IntercomWebServiceMessage>, auth: Data<super::IntercomAuth>, reg: Data<super::Users>, name: Path<String>) -> Result<HttpResponse, super::IntercomOpError> {
|
|
|
|
|
log::debug!("Got intercom message from {} to {:?}", name, body.public_ids.as_slice());
|
|
|
|
|
auth.validate(&req, &format!(".oj_services/{}/messages", name))?;
|
|
|
|
|
log::debug!("Authenticated intercom message from {} to {:?}", name, body.public_ids.as_slice());
|
2026-03-17 21:52:15 -04:00
|
|
|
reg.broadcast_web_service_message(body.0).await;
|
2025-10-26 15:43:51 -04:00
|
|
|
Ok(HttpResponse::NoContent().finish())
|
|
|
|
|
}
|