From f781afe99587d1ca8cd3b3f4316d4f201f927d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmet=20Kaan=20G=C3=BCm=C3=BC=C5=9F?= Date: Mon, 14 Apr 2025 16:13:42 +0300 Subject: [PATCH] refactor: :recycle: error, send and receive signals --- client/src/rtc.rs | 2 +- client/src/signal.rs | 97 +++++++++++++++++++++----------------------- protocol/src/lib.rs | 48 +++++++++++++++++++--- 3 files changed, 89 insertions(+), 58 deletions(-) diff --git a/client/src/rtc.rs b/client/src/rtc.rs index 123336b..84af0f4 100644 --- a/client/src/rtc.rs +++ b/client/src/rtc.rs @@ -37,7 +37,7 @@ pub async fn offer(username: String) { log!("{}", rtc_session_offer); let data = rtc_session_offer; - send_offer(&username, &data).await; + send_offer(&username, &data).await.unwrap(); } pub async fn answer() {} diff --git a/client/src/signal.rs b/client/src/signal.rs index ec68f99..fa4055b 100644 --- a/client/src/signal.rs +++ b/client/src/signal.rs @@ -1,43 +1,38 @@ -use std::{str::FromStr, sync::LazyLock}; +use std::sync::LazyLock; use leptos::logging::log; use protocol::{Signal, SignalType}; -use reqwest::{ - Response, - header::{HeaderMap, HeaderName}, -}; +use reqwest::{Response, header::HeaderMap}; use serde_json::{Value, json}; const SIGNALLING_ADDRESS: &str = "http://127.0.0.1:4546"; static REQUEST_CLIENT: LazyLock = LazyLock::new(|| reqwest::Client::new()); +async fn create_headers(headers: Vec<(&'static str, String)>) -> HeaderMap { + let mut header_map = HeaderMap::new(); + for (key, val) in headers { + header_map.insert(key, val.parse().unwrap()); + } + header_map +} + async fn post_json(username: &String, json: &Value) -> Result { - let mut headers = HeaderMap::new(); - headers - .try_insert( - HeaderName::from_str("username").unwrap(), - username.parse().unwrap(), - ) - .unwrap(); + let headers = create_headers(vec![]).await; REQUEST_CLIENT .post(SIGNALLING_ADDRESS) .headers(headers) + .bearer_auth(username) .json(json) .send() .await } -async fn get_json(username: &String) -> Result { - let mut headers = HeaderMap::new(); - headers - .try_insert( - HeaderName::from_str("username").unwrap(), - username.parse().unwrap(), - ) - .unwrap(); +async fn get_json(username: &String, signal_type: SignalType) -> Result { + let headers = create_headers(vec![("EXPECTED_SIGNAL", signal_type.to_string())]).await; REQUEST_CLIENT .get(SIGNALLING_ADDRESS) .headers(headers) + .bearer_auth(username) .send() .await } @@ -45,7 +40,7 @@ async fn get_json(username: &String) -> Result { pub async fn start_signalling(username: String) { log!("Start Signalling"); log!("{}\n{}", username, SIGNALLING_ADDRESS); - let auth_signal = Signal::new(&username, &SignalType::Auth, &"".to_owned()); + let auth_signal = Signal::new(&SignalType::Auth, &"".to_owned()); let json = json!(auth_signal); match post_json(&username, &json).await { Ok(signal_response) => log!("{:#?}", signal_response), @@ -55,42 +50,42 @@ pub async fn start_signalling(username: String) { } } -pub async fn send_offer(username: &String, data: &String) { - let rtc_session_offer_signal = Signal::new(username, &SignalType::Offer, data); +pub async fn send_offer(username: &String, data: &String) -> Result<(), reqwest::Error> { + let rtc_session_offer_signal = Signal::new(&SignalType::Offer, data); let rtc_session_offer_signal = json!(rtc_session_offer_signal); - match post_json(username, &rtc_session_offer_signal).await { - Ok(signal_response) => log!("{:#?}", signal_response), - Err(err_val) => { - log!("Error: Signal Post | {}", err_val); - } + post_json(username, &rtc_session_offer_signal) + .await + .map(|_| Ok(()))? +} + +pub async fn receive_offer(username: &String) -> Result> { + let result = get_json(username, SignalType::Offer) + .await + .map(async |response| response.json::().await)? + .await?; + if result.get_signal_type() == SignalType::Offer { + Ok(result) + } else { + Err(protocol::Error::SignalType(result.get_signal_type()))? } } -pub async fn receive_offer(username: &String) { - match get_json(username).await { - Ok(signal_response) => log!("{:#?}", signal_response), - Err(err_val) => { - log!("Error: Signal Post | {}", err_val); - } - } -} - -pub async fn send_answer(username: &String, data: &String) { - let rtc_session_answer_signal = Signal::new(username, &SignalType::Answer, data); +pub async fn send_answer(username: &String, data: &String) -> Result<(), reqwest::Error> { + let rtc_session_answer_signal = Signal::new(&SignalType::Answer, data); let rtc_session_answer_signal = json!(rtc_session_answer_signal); - match post_json(username, &rtc_session_answer_signal).await { - Ok(signal_response) => log!("{:#?}", signal_response), - Err(err_val) => { - log!("Error: Signal Post | {}", err_val); - } - } + post_json(username, &rtc_session_answer_signal) + .await + .map(|_| Ok(()))? } -pub async fn receive_answer(username: &String) { - match get_json(username).await { - Ok(signal_response) => log!("{:#?}", signal_response), - Err(err_val) => { - log!("Error: Signal Post | {}", err_val); - } +pub async fn receive_answer(username: &String) -> Result> { + let result = get_json(username, SignalType::Answer) + .await + .map(async |response| response.json::().await)? + .await?; + if result.get_signal_type() == SignalType::Answer { + Ok(result) + } else { + Err(protocol::Error::SignalType(result.get_signal_type()))? } } diff --git a/protocol/src/lib.rs b/protocol/src/lib.rs index 851dc52..09186f3 100644 --- a/protocol/src/lib.rs +++ b/protocol/src/lib.rs @@ -1,7 +1,30 @@ +use std::fmt::Display; + use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub enum Error { + SignalType(SignalType), +} + +impl std::error::Error for Error { + fn cause(&self) -> Option<&dyn std::error::Error> { + self.source() + } +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::SignalType(signal_type) => { + write!(f, "Not Expected Signal Type: {}", signal_type) + } + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub enum SignalType { Auth, Offer, @@ -10,25 +33,38 @@ pub enum SignalType { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Signal { - pub username: String, - pub signal_type: SignalType, - pub data: String, + signal_type: SignalType, + data: String, time: DateTime, } +impl Display for SignalType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SignalType::Auth => write!(f, "Auth"), + SignalType::Offer => write!(f, "Offer"), + SignalType::Answer => write!(f, "Answer"), + } + } +} + impl Signal { - pub fn new(username: &String, signal_type: &SignalType, data: &String) -> Signal { - let username = username.to_owned(); + pub fn new(signal_type: &SignalType, data: &String) -> Signal { let signal_type = *signal_type; let data = data.to_owned(); Signal { - username, signal_type, data, time: DateTime::default(), } } + pub fn get_signal_type(&self) -> SignalType { + self.signal_type + } + pub fn get_data(&self) -> String { + self.data.to_owned() + } pub fn get_time(&self) -> DateTime { self.time }