-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
abstract tx5 backend in prep for mock backend
- Loading branch information
Showing
8 changed files
with
320 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
//! Backend modules usable by tx5. | ||
|
||
use std::io::Result; | ||
use std::sync::Arc; | ||
|
||
use futures::future::BoxFuture; | ||
|
||
use crate::{Config, PubKey}; | ||
use tx5_core::deps::serde_json; | ||
|
||
#[cfg(feature = "backend-go-pion")] | ||
mod go_pion; | ||
|
||
/// Backend modules usable by tx5. | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] | ||
pub enum BackendModule { | ||
#[cfg(feature = "backend-go-pion")] | ||
/// The Go Pion-based backend. | ||
GoPion, | ||
|
||
#[cfg(feature = "backend-webrtc-rs")] | ||
/// The Webrtc-RS-based backend. | ||
WebrtcRs, | ||
|
||
/// The mock backend. | ||
Mock, | ||
} | ||
|
||
impl Default for BackendModule { | ||
#[allow(unreachable_code)] | ||
fn default() -> Self { | ||
#[cfg(feature = "backend-go-pion")] | ||
return Self::GoPion; | ||
#[cfg(feature = "backend-webrtc-rs")] | ||
return Self::WebrtcRs; | ||
Self::Mock | ||
} | ||
} | ||
|
||
impl BackendModule { | ||
/// Get a default version of the module-specific config. | ||
pub fn default_config(&self) -> serde_json::Value { | ||
match self { | ||
#[cfg(feature = "backend-go-pion")] | ||
Self::GoPion => go_pion::default_config(), | ||
#[cfg(feature = "backend-webrtc-rs")] | ||
Self::WebrtcRs => todo!(), | ||
Self::Mock => serde_json::json!({}), | ||
} | ||
} | ||
|
||
/// Connect a new backend module endpoint. | ||
pub async fn connect( | ||
&self, | ||
url: &str, | ||
listener: bool, | ||
config: &Arc<Config>, | ||
) -> Result<(DynBackEp, DynBackEpRecv)> { | ||
match self { | ||
#[cfg(feature = "backend-go-pion")] | ||
Self::GoPion => go_pion::connect(config, url, listener).await, | ||
#[cfg(feature = "backend-webrtc-rs")] | ||
Self::WebrtcRs => todo!(), | ||
Self::Mock => todo!(), | ||
} | ||
} | ||
} | ||
|
||
/// Backend connection. | ||
pub trait BackCon: 'static + Send + Sync { | ||
/// Send data over this backend connection. | ||
fn send(&self, data: Vec<u8>) -> BoxFuture<'_, Result<()>>; | ||
|
||
/// Get the pub_key identifying this connection. | ||
fn pub_key(&self) -> &PubKey; | ||
|
||
/// Returns `true` if we successfully connected over webrtc. | ||
// TODO - this isn't good encapsulation | ||
fn is_using_webrtc(&self) -> bool; | ||
|
||
/// Get connection statistics. | ||
// TODO - this isn't good encapsulation | ||
fn get_stats(&self) -> tx5_connection::ConnStats; | ||
} | ||
|
||
/// Trait-object version of backend connection. | ||
pub type DynBackCon = Arc<dyn BackCon + 'static + Send + Sync>; | ||
|
||
/// Backend connection receiver. | ||
pub trait BackConRecv: 'static + Send { | ||
/// Receive data from this backend connection. | ||
fn recv(&mut self) -> BoxFuture<'_, Option<Vec<u8>>>; | ||
} | ||
|
||
/// Trait-object version of backend connection receiver. | ||
pub type DynBackConRecv = Box<dyn BackConRecv + 'static + Send>; | ||
|
||
/// Pending connection. | ||
pub trait BackWaitCon: 'static + Send { | ||
/// Wait for the connection | ||
fn wait( | ||
&mut self, | ||
// TODO - this isn't good encapsulation | ||
recv_limit: Arc<tokio::sync::Semaphore>, | ||
) -> BoxFuture<'static, Result<(DynBackCon, DynBackConRecv)>>; | ||
|
||
/// Get the pub_key identifying this connection. | ||
fn pub_key(&self) -> &PubKey; | ||
} | ||
|
||
/// Trait-object version of backend wait con. | ||
pub type DynBackWaitCon = Box<dyn BackWaitCon + 'static + Send>; | ||
|
||
/// Backend endpoint. | ||
pub trait BackEp: 'static + Send + Sync { | ||
/// Establish an outgoing connection from this backend endpoint. | ||
fn connect(&self, pub_key: PubKey) | ||
-> BoxFuture<'_, Result<DynBackWaitCon>>; | ||
|
||
/// Get the pub_key identifying this endpoint. | ||
fn pub_key(&self) -> &PubKey; | ||
} | ||
|
||
/// Trait-object version of backend endpoint. | ||
pub type DynBackEp = Arc<dyn BackEp + 'static + Send + Sync>; | ||
|
||
/// Backend endpoint receiver. | ||
pub trait BackEpRecv: 'static + Send { | ||
/// Receive incoming connection from this backend endpoint. | ||
fn recv(&mut self) -> BoxFuture<'_, Option<DynBackWaitCon>>; | ||
} | ||
|
||
/// Trait-object version of backend endpoint receiver. | ||
pub type DynBackEpRecv = Box<dyn BackEpRecv + 'static + Send>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
//! go pion backend | ||
|
||
use super::*; | ||
use crate::Config; | ||
|
||
struct GoCon(tx5_connection::FramedConn); | ||
|
||
impl BackCon for GoCon { | ||
fn send(&self, data: Vec<u8>) -> BoxFuture<'_, Result<()>> { | ||
Box::pin(async { self.0.send(data).await }) | ||
} | ||
|
||
fn pub_key(&self) -> &PubKey { | ||
self.0.pub_key() | ||
} | ||
|
||
fn is_using_webrtc(&self) -> bool { | ||
self.0.is_using_webrtc() | ||
} | ||
|
||
fn get_stats(&self) -> tx5_connection::ConnStats { | ||
self.0.get_stats() | ||
} | ||
} | ||
|
||
struct GoConRecv(tx5_connection::FramedConnRecv); | ||
|
||
impl BackConRecv for GoConRecv { | ||
fn recv(&mut self) -> BoxFuture<'_, Option<Vec<u8>>> { | ||
Box::pin(async { self.0.recv().await }) | ||
} | ||
} | ||
|
||
struct GoWaitCon( | ||
PubKey, | ||
Option<Arc<tx5_connection::Conn>>, | ||
Option<tx5_connection::ConnRecv>, | ||
); | ||
|
||
impl BackWaitCon for GoWaitCon { | ||
fn wait( | ||
&mut self, | ||
recv_limit: Arc<tokio::sync::Semaphore>, | ||
) -> BoxFuture<'static, Result<(DynBackCon, DynBackConRecv)>> { | ||
let con = self.1.take(); | ||
let con_recv = self.2.take(); | ||
Box::pin(async move { | ||
let (con, con_recv) = match (con, con_recv) { | ||
(_, None) | (None, _) => { | ||
return Err(std::io::Error::other("already awaited")) | ||
} | ||
(Some(con), Some(con_recv)) => (con, con_recv), | ||
}; | ||
|
||
con.ready().await; | ||
|
||
let (con, con_recv) = | ||
tx5_connection::FramedConn::new(con, con_recv, recv_limit) | ||
.await?; | ||
|
||
let con: DynBackCon = Arc::new(GoCon(con)); | ||
let con_recv: DynBackConRecv = Box::new(GoConRecv(con_recv)); | ||
|
||
Ok((con, con_recv)) | ||
}) | ||
} | ||
|
||
fn pub_key(&self) -> &PubKey { | ||
&self.0 | ||
} | ||
} | ||
|
||
struct GoEp(tx5_connection::Hub); | ||
|
||
impl BackEp for GoEp { | ||
fn connect( | ||
&self, | ||
pub_key: PubKey, | ||
) -> BoxFuture<'_, Result<DynBackWaitCon>> { | ||
Box::pin(async { | ||
let (con, con_recv) = self.0.connect(pub_key).await?; | ||
let pub_key = con.pub_key().clone(); | ||
let wc: DynBackWaitCon = | ||
Box::new(GoWaitCon(pub_key, Some(con), Some(con_recv))); | ||
Ok(wc) | ||
}) | ||
} | ||
|
||
fn pub_key(&self) -> &PubKey { | ||
self.0.pub_key() | ||
} | ||
} | ||
|
||
struct GoEpRecv(tx5_connection::HubRecv); | ||
|
||
impl BackEpRecv for GoEpRecv { | ||
fn recv(&mut self) -> BoxFuture<'_, Option<DynBackWaitCon>> { | ||
Box::pin(async { | ||
if let Some((con, con_recv)) = self.0.accept().await { | ||
let pub_key = con.pub_key().clone(); | ||
let wc: DynBackWaitCon = | ||
Box::new(GoWaitCon(pub_key, Some(con), Some(con_recv))); | ||
Some(wc) | ||
} else { | ||
None | ||
} | ||
}) | ||
} | ||
} | ||
|
||
/// Get a default version of the module-specific config. | ||
pub fn default_config() -> serde_json::Value { | ||
serde_json::json!({}) | ||
} | ||
|
||
/// Connect a new backend based on the tx5-go-pion backend. | ||
pub async fn connect( | ||
config: &Arc<Config>, | ||
url: &str, | ||
listener: bool, | ||
) -> Result<(DynBackEp, DynBackEpRecv)> { | ||
let webrtc_config = config.initial_webrtc_config.clone().into_bytes(); | ||
let sig_config = tx5_connection::tx5_signal::SignalConfig { | ||
listener, | ||
allow_plain_text: config.signal_allow_plain_text, | ||
//max_connections: config.connection_count_max as usize, | ||
max_idle: config.timeout, | ||
..Default::default() | ||
}; | ||
let (hub, hub_recv) = | ||
tx5_connection::Hub::new(webrtc_config, url, Arc::new(sig_config)) | ||
.await?; | ||
let ep: DynBackEp = Arc::new(GoEp(hub)); | ||
let ep_recv: DynBackEpRecv = Box::new(GoEpRecv(hub_recv)); | ||
Ok((ep, ep_recv)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.