UI Corners & Pingpong
This commit is contained in:
parent
cbd357ce14
commit
befc35bbfd
7 changed files with 267 additions and 194 deletions
|
|
@ -1,113 +1,61 @@
|
|||
use crate::APP_STATE;
|
||||
use crate::data::communication::{CommunicationType, CommunicationValue, DataTypes};
|
||||
use crate::gui::log_panel::AppState;
|
||||
use crate::gui::log_panel::{log_message, log_message_trans};
|
||||
use crate::omikron::omikron_connection::OmikronConnection;
|
||||
use color_eyre::owo_colors::OwoColorize;
|
||||
use crate::users::contact::Contact;
|
||||
use crate::users::user_community_util::UserCommunityUtil;
|
||||
use crate::util::chat_files::ChatFiles;
|
||||
use crate::util::chats_util::{get_user, get_users, mod_user};
|
||||
use futures_util::{SinkExt, StreamExt};
|
||||
use std::arch::x86_64::_SIDD_MASKED_NEGATIVE_POLARITY;
|
||||
use json::JsonValue;
|
||||
use json::number::Number;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Deref;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tokio::net::TcpStream;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::time::{Duration, Instant, sleep};
|
||||
use tokio_tungstenite::{
|
||||
MaybeTlsStream, WebSocketStream, connect_async, tungstenite::protocol::Message,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct PingPongTask {
|
||||
pub parent: Arc<OmikronConnection>,
|
||||
pub message_send_times: Arc<Mutex<HashMap<Uuid, Instant>>>,
|
||||
pub no_ping_in: Arc<Mutex<i32>>,
|
||||
pub last_ping: Arc<Mutex<Option<u64>>>,
|
||||
}
|
||||
fn assert_send_sync<T: Send + Sync>() {}
|
||||
impl OmikronConnection {
|
||||
pub async fn send_ping(&self) {
|
||||
let uuid = Uuid::new_v4();
|
||||
let send_time = Instant::now();
|
||||
|
||||
#[test]
|
||||
fn check_omikron_connection_send_sync() {
|
||||
assert_send_sync::<OmikronConnection>();
|
||||
}
|
||||
self.message_send_times.lock().await.insert(uuid, send_time);
|
||||
self.send_ping_message(uuid).await;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_pingpong_task_send_sync() {
|
||||
assert_send_sync::<PingPongTask>();
|
||||
}
|
||||
impl PingPongTask {
|
||||
pub fn new(parent: Arc<OmikronConnection>) -> Self {
|
||||
let message_send_times = Arc::new(Mutex::new(HashMap::new()));
|
||||
let no_ping_in = Arc::new(Mutex::new(-1));
|
||||
let last_ping = Arc::new(Mutex::new(None));
|
||||
pub async fn send_ping_message(&self, uuid: Uuid) {
|
||||
let ping_message = CommunicationValue::new(CommunicationType::ping)
|
||||
.with_id(uuid)
|
||||
.add_data_num(DataTypes::last_ping, Number::from(2))
|
||||
.to_json()
|
||||
.to_string();
|
||||
|
||||
let task = PingPongTask {
|
||||
parent: parent.clone(),
|
||||
message_send_times: message_send_times.clone(),
|
||||
no_ping_in: no_ping_in.clone(),
|
||||
last_ping: last_ping.clone(),
|
||||
self.send_message(ping_message).await;
|
||||
}
|
||||
|
||||
/// Handles incoming pong and calculates latency
|
||||
pub async fn handle_pong(&self, cv: &CommunicationValue, log: bool) {
|
||||
let id = cv.get_id();
|
||||
let send_time_opt = {
|
||||
let queue = self.message_send_times.lock().await;
|
||||
queue.get(&id).cloned()
|
||||
};
|
||||
|
||||
task
|
||||
}
|
||||
if let Some(send_time) = send_time_opt {
|
||||
let ping = Instant::now().duration_since(send_time).as_millis() as f64;
|
||||
self.message_send_times.lock().await.remove(&id);
|
||||
|
||||
pub fn send_ping(&self) {
|
||||
let sel = self.clone();
|
||||
tokio::spawn(async move {
|
||||
let uuid = Uuid::new_v4();
|
||||
let send_time = Instant::now();
|
||||
let mut message_send_times = sel.message_send_times.lock().await;
|
||||
message_send_times.insert(uuid, send_time);
|
||||
|
||||
let no_ping_in_val = {
|
||||
let no_ping_in = sel.no_ping_in.lock().await;
|
||||
*no_ping_in
|
||||
};
|
||||
|
||||
if no_ping_in_val != -1 {
|
||||
sel.handle_slow_connection(no_ping_in_val).await;
|
||||
} else {
|
||||
sel.parent.send_ping_message(uuid).await;
|
||||
if log {
|
||||
APP_STATE.lock().unwrap().push_ping_val(ping);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn handle_slow_connection(&self, no_ping_in: i32) {
|
||||
if no_ping_in > 8 {
|
||||
self.parent.reconnect().await;
|
||||
self.reconnect().await;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn reconnect(&self) {
|
||||
let mut no_ping_in = self.no_ping_in.lock().await;
|
||||
*no_ping_in = -1;
|
||||
}
|
||||
|
||||
pub fn handle_pong(&self, cv: &CommunicationValue, log: bool) {
|
||||
let sel = self.clone();
|
||||
let cv = cv.clone();
|
||||
tokio::spawn(async move {
|
||||
let send_time = {
|
||||
let message_send_times = sel.message_send_times.lock().await;
|
||||
message_send_times.get(&cv.get_id()).cloned()
|
||||
};
|
||||
|
||||
if let Some(send_time) = send_time {
|
||||
let receive_time = Instant::now();
|
||||
let ping = receive_time.duration_since(send_time).as_millis() as u64;
|
||||
|
||||
let mut last_ping = sel.last_ping.lock().await;
|
||||
*last_ping = Some(ping);
|
||||
let mut no_ping_in = sel.no_ping_in.lock().await;
|
||||
*no_ping_in = -1;
|
||||
let mut message_send_times = sel.message_send_times.lock().await;
|
||||
message_send_times.remove(&cv.get_id());
|
||||
|
||||
if log {
|
||||
APP_STATE.lock().unwrap().push_log("12.0".to_string());
|
||||
APP_STATE.lock().unwrap().push_ping_val(12.0);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
pub async fn cancel(&self) {
|
||||
let mut no_ping_in = self.no_ping_in.lock().await;
|
||||
*no_ping_in = -1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue