fix: browser freezing because of blocking channel

This commit is contained in:
Ahmet Kaan Gümüş 2025-04-26 03:34:07 +03:00
parent 8391ef31ba
commit 1e27b9280e
9 changed files with 172 additions and 386 deletions

View file

@ -1,82 +1,25 @@
use std::sync::{Arc, LazyLock, RwLock};
use axum::{
Extension, Json, Router,
http::StatusCode,
response::IntoResponse,
routing::{get, post},
};
use axum_macros::debug_handler;
use protocol::{Signal, User, UserAndSignal};
use fastwebsockets::{FragmentCollector, OpCode, Role, WebSocket};
use tokio::net::TcpListener;
use tower_http::{cors::CorsLayer, trace::TraceLayer};
use crate::middleware::{
UserAndExpectedSignal, verify_then_get_user, verify_then_get_user_and_expected_signal,
};
static USERS_AND_SIGNALS: LazyLock<RwLock<Vec<UserAndSignal>>> =
LazyLock::new(|| RwLock::new(vec![]));
const SERVER_ADDRESS: &str = "192.168.1.3:4546";
pub async fn start_signalling() {
let route = route()
.layer(CorsLayer::permissive())
.layer(TraceLayer::new_for_http());
let listener = TcpListener::bind("192.168.1.3:4546").await.unwrap();
println!("http://192.168.1.3:4546");
axum::serve(listener, route).await.unwrap();
}
let tcp_listener = TcpListener::bind(SERVER_ADDRESS).await.unwrap();
while let Ok((tcp_stream, client_address)) = tcp_listener.accept().await {
let mut websocket = WebSocket::after_handshake(tcp_stream, Role::Server);
websocket.set_writev(false);
websocket.set_auto_close(true);
websocket.set_auto_pong(true);
let mut websocket = FragmentCollector::new(websocket);
fn route() -> Router {
Router::new()
.route("/alive", get(alive))
.route(
"/",
get(read_signal).route_layer(axum::middleware::from_fn(
verify_then_get_user_and_expected_signal,
)),
)
.route(
"/",
post(create_signal).route_layer(axum::middleware::from_fn(verify_then_get_user)),
)
}
async fn alive() -> impl IntoResponse {
StatusCode::OK
}
#[debug_handler]
async fn create_signal(
Extension(user): Extension<Arc<User>>,
Json(signal): Json<Signal>,
) -> impl IntoResponse {
let user = (*user).clone();
let user_and_signal = UserAndSignal::new(user, signal).await;
USERS_AND_SIGNALS.write().unwrap().push(user_and_signal);
StatusCode::OK
}
#[debug_handler]
async fn read_signal(
Extension(user_and_expected_signal): Extension<Arc<UserAndExpectedSignal>>,
) -> impl IntoResponse {
let mut target_index = None;
let mut json_body = serde_json::json!("");
for (index, user_and_signal) in USERS_AND_SIGNALS.read().unwrap().iter().enumerate() {
if user_and_signal.signal.get_signal_type() == user_and_expected_signal.expected_signal
&& user_and_signal.user != user_and_expected_signal.user
{
json_body = serde_json::json!(user_and_signal);
target_index = Some(index);
while let Ok(received_frame) = websocket.read_frame().await {
if let OpCode::Text = received_frame.opcode {
let received_payload = received_frame.payload;
println!(
"Client: {:#?} | Sent:\n{:#?}",
client_address, received_payload
);
}
}
}
match target_index {
Some(target_index) => {
USERS_AND_SIGNALS.write().unwrap().remove(target_index);
(StatusCode::OK, Json(json_body)).into_response()
}
None => StatusCode::BAD_REQUEST.into_response(),
}
}