fix: 🐛 Timeout connection if lingering

This commit is contained in:
Riccardo Zaglia 2023-09-05 16:02:07 +08:00
parent 0b3fcad350
commit 79eff14c25
3 changed files with 42 additions and 15 deletions

View File

@ -22,7 +22,7 @@ use alvr_packets::{
use alvr_session::{settings_schema::Switch, SessionConfig};
use alvr_sockets::{
ControlSocketSender, PeerType, ProtoControlSocket, StreamSender, StreamSocketBuilder,
KEEPALIVE_INTERVAL,
KEEPALIVE_INTERVAL, KEEPALIVE_TIMEOUT,
};
use serde_json as json;
use std::{
@ -52,6 +52,7 @@ const NETWORK_UNREACHABLE_MESSAGE: &str = "Cannot connect to the internet";
const STREAM_STARTING_MESSAGE: &str = "The stream will begin soon\nPlease wait...";
const SERVER_RESTART_MESSAGE: &str = "The streamer is restarting\nPlease wait...";
const SERVER_DISCONNECTED_MESSAGE: &str = "The streamer has disconnected.";
const CONNECTION_TIMEOUT_MESSAGE: &str = "Connection timeout.";
const DISCOVERY_RETRY_PAUSE: Duration = Duration::from_millis(500);
const RETRY_CONNECT_MIN_INTERVAL: Duration = Duration::from_secs(1);
@ -454,6 +455,7 @@ fn connection_pipeline(
});
let control_receive_thread = thread::spawn(move || {
let mut disconnection_deadline = Instant::now() + KEEPALIVE_TIMEOUT;
while IS_STREAMING.value() {
let maybe_packet = control_receiver.recv(STREAMING_RECV_TIMEOUT);
@ -471,7 +473,19 @@ fn connection_pipeline(
return;
}
Ok(_) => (),
Err(ConnectionError::TryAgain(_)) => continue,
Err(ConnectionError::TryAgain(_)) => {
if Instant::now() > disconnection_deadline {
info!("{CONNECTION_TIMEOUT_MESSAGE}");
set_hud_message(CONNECTION_TIMEOUT_MESSAGE);
if let Some(notifier) = &*DISCONNECT_SERVER_NOTIFIER.lock() {
notifier.send(()).ok();
}
return;
} else {
continue;
}
}
Err(e) => {
info!("{SERVER_DISCONNECTED_MESSAGE} Cause: {e}");
set_hud_message(SERVER_DISCONNECTED_MESSAGE);
@ -482,6 +496,8 @@ fn connection_pipeline(
return;
}
}
disconnection_deadline = Instant::now() + KEEPALIVE_TIMEOUT;
}
});

View File

@ -30,6 +30,7 @@ use alvr_packets::{
use alvr_session::{CodecType, ConnectionState, ControllersEmulationMode, FrameSize, OpenvrConfig};
use alvr_sockets::{
PeerType, ProtoControlSocket, StreamSender, StreamSocketBuilder, KEEPALIVE_INTERVAL,
KEEPALIVE_TIMEOUT,
};
use std::{
collections::HashMap,
@ -854,24 +855,21 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
let control_sender = Arc::clone(&control_sender);
let client_hostname = client_hostname.clone();
move || {
let mut disconnection_deadline = Instant::now() + KEEPALIVE_TIMEOUT;
while IS_STREAMING.value() {
let packet = match control_receiver.recv(STREAMING_RECV_TIMEOUT) {
Ok(packet) => packet,
Err(ConnectionError::TryAgain(_)) => continue,
Err(ConnectionError::TryAgain(_)) => {
if Instant::now() > disconnection_deadline {
info!("Client disconnected. Timeout");
break;
} else {
continue;
}
}
Err(e) => {
info!("Client disconnected. Cause: {e}");
SERVER_DATA_MANAGER.write().update_client_list(
client_hostname,
ClientListAction::SetConnectionState(ConnectionState::Disconnecting {
should_be_removed: false,
}),
);
if let Some(notifier) = &*DISCONNECT_CLIENT_NOTIFIER.lock() {
notifier.send(ClientDisconnectRequest::Disconnect).ok();
}
return;
break;
}
};
@ -980,6 +978,18 @@ fn try_connect(mut client_ips: HashMap<IpAddr, String>) -> ConResult {
}
_ => (),
}
disconnection_deadline = Instant::now() + KEEPALIVE_TIMEOUT;
}
SERVER_DATA_MANAGER.write().update_client_list(
client_hostname,
ClientListAction::SetConnectionState(ConnectionState::Disconnecting {
should_be_removed: false,
}),
);
if let Some(notifier) = &*DISCONNECT_CLIENT_NOTIFIER.lock() {
notifier.send(ClientDisconnectRequest::Disconnect).ok();
}
}
});

View File

@ -16,6 +16,7 @@ pub const LOCAL_IP: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED);
pub const CONTROL_PORT: u16 = 9943;
pub const HANDSHAKE_PACKET_SIZE_BYTES: usize = 56; // this may change in future protocols
pub const KEEPALIVE_INTERVAL: Duration = Duration::from_millis(500);
pub const KEEPALIVE_TIMEOUT: Duration = Duration::from_secs(2);
fn set_socket_buffers(
socket: &socket2::Socket,