use cs_utils::random_str;
use tokio::try_join;
use tokio::io::duplex;
use webrtc::{peer_connection::configuration::RTCConfiguration, ice_transport::ice_server::RTCIceServer};
use connection_utils::{Channel, Connected};
use crate::rtc_connection::RtcConnection;
type TConnection = Box<dyn Connected>;
type TChannel = Box<dyn Channel>;
pub async fn create_connection_pair() -> (TConnection, TConnection) {
let (stream1, stream2 ) = duplex(4096);
let rtc_config1 = RTCConfiguration {
ice_servers: vec![RTCIceServer {
urls: vec!["stun:stun.l.google.com:19302".to_owned()],
..Default::default()
}],
..Default::default()
};
let rtc_config2 = RTCConfiguration {
ice_servers: vec![RTCIceServer {
urls: vec!["stun:stun.l.google.com:19302".to_owned()],
..Default::default()
}],
..Default::default()
};
let (client_connection, server_connection) = try_join!(
tokio::spawn(async move {
let connection = RtcConnection::new(
Box::new(stream1),
rtc_config1,
)
.await
.expect("Cannot create RTC connection.");
return connection
.connect()
.await
.expect("Failed to connect.");
}),
tokio::spawn(async move {
let connection = RtcConnection::new(
Box::new(stream2),
rtc_config2,
)
.await
.expect("Cannot create RTC connection.");
return connection
.listen()
.await
.expect("Failed to connect.");
}),
).unwrap();
return (client_connection, server_connection);
}
pub async fn create_channel_pair(
mut client_connection: TConnection,
mut server_connection: TConnection,
) -> ((TConnection, TChannel), (TConnection, TChannel)) {
let data_channel_label = format!("channel:{}", random_str(8));
let (client_channel, server_channel) = try_join!(
tokio::spawn(async move {
let data_channel = client_connection
.channel(data_channel_label)
.await
.expect("Cannot create data channel.");
return (client_connection, data_channel);
}),
tokio::spawn(async move {
let mut on_remote_channel = server_connection.on_remote_channel()
.expect("Cannot get \"on_remote_channel\" stream.");
while let Some(channel) = on_remote_channel.recv().await {
server_connection.off_remote_channel(on_remote_channel).unwrap();
return (server_connection, channel);
}
panic!("Failed to receive a remote data channel.");
}),
).unwrap();
return (client_channel, server_channel);
}
pub async fn create_channels(
channels_count: usize,
) -> Vec<(TChannel, TChannel)> {
let (
mut client_connection,
mut server_connection,
) = create_connection_pair().await;
let channels = {
let mut result = vec![];
for _ in 0..channels_count {
let (
(client_connection2, client_channel),
(server_connection2, server_channel)) = create_channel_pair(
client_connection,
server_connection,
).await;
client_connection = client_connection2;
server_connection = server_connection2;
result.push((client_channel, server_channel));
}
result
};
return channels;
}