118 lines
3.9 KiB
Rust
118 lines
3.9 KiB
Rust
use crate::command::command_handle::CommandHandle;
|
|
use crate::command::service::CommandManagementService;
|
|
use crate::telemetry::management_service::TelemetryManagementService;
|
|
use actix_ws::{AggregatedMessage, ProtocolError, Session};
|
|
use anyhow::bail;
|
|
use api::messages::payload::RequestMessagePayload;
|
|
use api::messages::{RequestMessage, ResponseMessage};
|
|
use std::sync::Arc;
|
|
use tokio::sync::mpsc::{Receiver, Sender};
|
|
use uuid::Uuid;
|
|
|
|
pub(super) struct BackendConnection {
|
|
session: Session,
|
|
tlm_management: Arc<TelemetryManagementService>,
|
|
cmd_management: Arc<CommandManagementService>,
|
|
tx: Sender<ResponseMessage>,
|
|
commands: Vec<CommandHandle>,
|
|
pub rx: Receiver<ResponseMessage>,
|
|
pub should_close: bool,
|
|
}
|
|
|
|
impl BackendConnection {
|
|
pub fn new(
|
|
session: Session,
|
|
tlm_management: Arc<TelemetryManagementService>,
|
|
cmd_management: Arc<CommandManagementService>,
|
|
) -> Self {
|
|
let (tx, rx) = tokio::sync::mpsc::channel::<ResponseMessage>(128);
|
|
Self {
|
|
session,
|
|
tlm_management,
|
|
cmd_management,
|
|
tx,
|
|
commands: vec![],
|
|
rx,
|
|
should_close: false,
|
|
}
|
|
}
|
|
|
|
async fn handle_request(&mut self, msg: RequestMessage) -> anyhow::Result<()> {
|
|
match msg.payload {
|
|
RequestMessagePayload::TelemetryDefinitionRequest(tlm_def) => {
|
|
self.tx
|
|
.send(ResponseMessage {
|
|
uuid: Uuid::new_v4(),
|
|
response: Some(msg.uuid),
|
|
payload: self.tlm_management.register(tlm_def)?.into(),
|
|
})
|
|
.await?;
|
|
}
|
|
RequestMessagePayload::TelemetryEntry(tlm_entry) => {
|
|
self.tlm_management.add_tlm_item(tlm_entry)?;
|
|
}
|
|
RequestMessagePayload::GenericCallbackError(_) => todo!(),
|
|
RequestMessagePayload::CommandDefinition(def) => {
|
|
let cmd = self
|
|
.cmd_management
|
|
.register_command(msg.uuid, def, self.tx.clone())?;
|
|
self.commands.push(cmd);
|
|
}
|
|
RequestMessagePayload::CommandResponse(response) => match msg.response {
|
|
None => bail!("Command Response Payload Must Respond to a Command"),
|
|
Some(uuid) => {
|
|
self.cmd_management
|
|
.handle_command_response(uuid, response)
|
|
.await?;
|
|
}
|
|
},
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn handle_request_message(
|
|
&mut self,
|
|
msg: Result<AggregatedMessage, ProtocolError>,
|
|
) -> anyhow::Result<()> {
|
|
let msg = msg?;
|
|
match msg {
|
|
AggregatedMessage::Text(data) => {
|
|
self.handle_request(serde_json::from_str(&data)?).await?;
|
|
}
|
|
AggregatedMessage::Binary(_) => {
|
|
bail!("Binary Messages Unsupported");
|
|
}
|
|
AggregatedMessage::Ping(bytes) => {
|
|
self.session.pong(&bytes).await?;
|
|
}
|
|
AggregatedMessage::Pong(_) => {
|
|
// Intentionally Ignore
|
|
}
|
|
AggregatedMessage::Close(_) => {
|
|
self.should_close = true;
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn handle_response(&mut self, msg: ResponseMessage) -> anyhow::Result<()> {
|
|
let msg_json = serde_json::to_string(&msg)?;
|
|
self.session.text(msg_json).await?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn cleanup(mut self) {
|
|
self.rx.close();
|
|
// Clone here to prevent conflict with the Drop trait
|
|
let _ = self.session.clone().close(None).await;
|
|
}
|
|
}
|
|
|
|
impl Drop for BackendConnection {
|
|
fn drop(&mut self) {
|
|
for command in self.commands.drain(..) {
|
|
self.cmd_management.unregister(command);
|
|
}
|
|
}
|
|
}
|