feat: ✨ web and websocket server
This commit is contained in:
parent
1e27b9280e
commit
64e89b006a
4 changed files with 49 additions and 26 deletions
|
@ -1,5 +1,3 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use leptos::{
|
use leptos::{
|
||||||
IntoView,
|
IntoView,
|
||||||
html::{ElementChild, button, label},
|
html::{ElementChild, button, label},
|
||||||
|
@ -7,7 +5,6 @@ use leptos::{
|
||||||
prelude::{OnAttribute, Read, Show, ShowProps, ToChildren},
|
prelude::{OnAttribute, Read, Show, ShowProps, ToChildren},
|
||||||
server::LocalResource,
|
server::LocalResource,
|
||||||
};
|
};
|
||||||
use wasm_bindgen_futures::spawn_local;
|
|
||||||
|
|
||||||
use crate::{media::audio, webrtc::WebRTC};
|
use crate::{media::audio, webrtc::WebRTC};
|
||||||
|
|
||||||
|
@ -21,9 +18,6 @@ pub fn app() -> impl IntoView {
|
||||||
let audio_stream = audio_stream.as_deref().unwrap().clone();
|
let audio_stream = audio_stream.as_deref().unwrap().clone();
|
||||||
|
|
||||||
let webrtc = WebRTC::new(Some(audio_stream), None, None).unwrap();
|
let webrtc = WebRTC::new(Some(audio_stream), None, None).unwrap();
|
||||||
let webrtc = Arc::new(webrtc);
|
|
||||||
let webrtc_init = webrtc.clone();
|
|
||||||
spawn_local(async move { webrtc_init.init().await });
|
|
||||||
|
|
||||||
let webrtc_offer = webrtc.clone();
|
let webrtc_offer = webrtc.clone();
|
||||||
let offer_button = button()
|
let offer_button = button()
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use leptos::logging::log;
|
use leptos::logging::log;
|
||||||
use protocol::Error;
|
use protocol::Error;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::{JsFuture, spawn_local};
|
||||||
use web_sys::{
|
use web_sys::{
|
||||||
MediaStream, RtcConfiguration, RtcIceCandidate, RtcIceCandidateInit, RtcIceServer,
|
MediaStream, RtcConfiguration, RtcIceCandidate, RtcIceCandidateInit, RtcIceServer,
|
||||||
RtcPeerConnection, RtcPeerConnectionIceEvent, RtcPeerConnectionState, RtcSdpType,
|
RtcPeerConnection, RtcPeerConnectionIceEvent, RtcPeerConnectionState, RtcSdpType,
|
||||||
|
@ -26,7 +28,7 @@ impl WebRTC {
|
||||||
audio_stream: Option<MediaStream>,
|
audio_stream: Option<MediaStream>,
|
||||||
video_stream: Option<MediaStream>,
|
video_stream: Option<MediaStream>,
|
||||||
screen_stream: Option<MediaStream>,
|
screen_stream: Option<MediaStream>,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Arc<Self>, Error> {
|
||||||
let ice_server_addresses = vec![JsValue::from("stun:stun.l.google.com:19302")]
|
let ice_server_addresses = vec![JsValue::from("stun:stun.l.google.com:19302")]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Array>();
|
.collect::<Array>();
|
||||||
|
@ -58,12 +60,16 @@ impl WebRTC {
|
||||||
video_stream,
|
video_stream,
|
||||||
screen_stream,
|
screen_stream,
|
||||||
};
|
};
|
||||||
|
let webrtc = Arc::new(webrtc);
|
||||||
|
|
||||||
webrtc.add_streams();
|
webrtc.add_streams();
|
||||||
|
let webrtc_ice_candidate_receiver = webrtc.clone();
|
||||||
|
spawn_local(async move { webrtc_ice_candidate_receiver.ice_candidate_receiver().await });
|
||||||
|
|
||||||
Ok(webrtc)
|
Ok(webrtc)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn init(&self) {
|
async fn ice_candidate_receiver(&self) {
|
||||||
while let Ok(received_ice_candidate) = receive_ice_candidate().await {
|
while let Ok(received_ice_candidate) = receive_ice_candidate().await {
|
||||||
let received_ice_candidate =
|
let received_ice_candidate =
|
||||||
RtcIceCandidateInit::new(&received_ice_candidate.get_data());
|
RtcIceCandidateInit::new(&received_ice_candidate.get_data());
|
||||||
|
|
|
@ -5,7 +5,9 @@ edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio = { version = "1.42.1", default-features = false, features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.42.1", default-features = false, features = ["macros", "rt-multi-thread"] }
|
||||||
fastwebsockets = "0.10.0"
|
axum = "0.8.3"
|
||||||
|
tower-http = { version = "0.6.2", default-features = false, features = ["cors"]}
|
||||||
|
fastwebsockets = { version = "0.10.0", features = ["upgrade", "with_axum"]}
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
|
|
|
@ -1,25 +1,46 @@
|
||||||
use fastwebsockets::{FragmentCollector, OpCode, Role, WebSocket};
|
use axum::{Router, http::StatusCode, response::IntoResponse, routing::get};
|
||||||
|
use fastwebsockets::{
|
||||||
|
OpCode,
|
||||||
|
upgrade::{IncomingUpgrade, UpgradeFut},
|
||||||
|
};
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
use tower_http::cors::CorsLayer;
|
||||||
|
|
||||||
const SERVER_ADDRESS: &str = "192.168.1.3:4546";
|
const SERVER_ADDRESS: &str = "192.168.1.3:4546";
|
||||||
|
|
||||||
pub async fn start_signalling() {
|
pub async fn start_signalling() {
|
||||||
let tcp_listener = TcpListener::bind(SERVER_ADDRESS).await.unwrap();
|
let router = Router::new()
|
||||||
while let Ok((tcp_stream, client_address)) = tcp_listener.accept().await {
|
.route("/", get(alive))
|
||||||
let mut websocket = WebSocket::after_handshake(tcp_stream, Role::Server);
|
.route("/signal", get(signal))
|
||||||
|
.layer(CorsLayer::permissive());
|
||||||
|
|
||||||
|
let listener = TcpListener::bind(SERVER_ADDRESS).await.unwrap();
|
||||||
|
|
||||||
|
println!("{}", SERVER_ADDRESS);
|
||||||
|
axum::serve(listener, router).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn alive() -> impl IntoResponse {
|
||||||
|
StatusCode::OK
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn signal(websocket: IncomingUpgrade) -> impl IntoResponse {
|
||||||
|
let (response, websocket) = websocket.upgrade().unwrap();
|
||||||
|
tokio::spawn(websocket_handler(websocket));
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn websocket_handler(websocket: UpgradeFut) {
|
||||||
|
let mut websocket = websocket.await.unwrap();
|
||||||
|
|
||||||
|
websocket.set_auto_pong(true);
|
||||||
websocket.set_writev(false);
|
websocket.set_writev(false);
|
||||||
websocket.set_auto_close(true);
|
websocket.set_auto_close(true);
|
||||||
websocket.set_auto_pong(true);
|
|
||||||
let mut websocket = FragmentCollector::new(websocket);
|
|
||||||
|
|
||||||
while let Ok(received_frame) = websocket.read_frame().await {
|
while let Ok(received_frame) = websocket.read_frame().await {
|
||||||
if let OpCode::Text = received_frame.opcode {
|
if let OpCode::Text = received_frame.opcode {
|
||||||
let received_payload = received_frame.payload;
|
let received_payload = received_frame.payload;
|
||||||
println!(
|
println!("Sent:\n{:#?}", received_payload);
|
||||||
"Client: {:#?} | Sent:\n{:#?}",
|
|
||||||
client_address, received_payload
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue