add sending keepalive packets

This commit is contained in:
Rokas Puzonas 2023-05-14 14:13:07 +03:00
parent 4ef0edc9c3
commit 288903e0e9
2 changed files with 37 additions and 14 deletions

View File

@ -21,7 +21,7 @@ smol = "1.3.0"
ssh2 = "0.9.4" ssh2 = "0.9.4"
syntect = "5.0.0" syntect = "5.0.0"
thiserror = "1.0.40" thiserror = "1.0.40"
tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.26.0", features = ["macros", "rt-multi-thread", "time"] }
toml = "0.7.3" toml = "0.7.3"
version = "3.0.0" version = "3.0.0"

View File

@ -1,10 +1,10 @@
use std::{ use std::{
net::{SocketAddr, SocketAddrV4}, net::{SocketAddr, SocketAddrV4},
sync::{mpsc::{Receiver, Sender}, Arc}, sync::{mpsc::{Receiver, Sender}, Arc},
vec, rc::Rc, time::SystemTime, path::{PathBuf, Path}, fs, vec, rc::Rc, time::{SystemTime, Duration}, path::{PathBuf, Path}, fs,
}; };
use anyhow::{Result, anyhow}; use anyhow::Result;
use async_ssh2_lite::{AsyncIoTcpStream, AsyncSession}; use async_ssh2_lite::{AsyncIoTcpStream, AsyncSession};
use directories_next::ProjectDirs; use directories_next::ProjectDirs;
use eframe::CreationContext; use eframe::CreationContext;
@ -64,6 +64,7 @@ pub struct App {
session: Option<AsyncSession<AsyncIoTcpStream>>, session: Option<AsyncSession<AsyncIoTcpStream>>,
ubus_call_handle: Option<JoinHandle<()>>, ubus_call_handle: Option<JoinHandle<()>>,
last_ubus_call_at: SystemTime, last_ubus_call_at: SystemTime,
keepalive_handle: Option<JoinHandle<()>>,
selected_object: Option<Rc<ubus::Object>>, selected_object: Option<Rc<ubus::Object>>,
selected_method: Option<String>, selected_method: Option<String>,
@ -104,6 +105,7 @@ impl Default for App {
}, },
session: None, session: None,
ubus_call_handle: None, ubus_call_handle: None,
keepalive_handle: None,
last_ubus_call_at: SystemTime::UNIX_EPOCH, last_ubus_call_at: SystemTime::UNIX_EPOCH,
object_filter: "".into(), object_filter: "".into(),
@ -131,7 +133,7 @@ async fn connect<A>(
password: String, password: String,
) -> Result<AsyncSession<AsyncIoTcpStream>> ) -> Result<AsyncSession<AsyncIoTcpStream>>
where where
A: Into<SocketAddr>, A: Into<SocketAddr>
{ {
let mut session = AsyncSession::<AsyncIoTcpStream>::connect(socket_addr, None).await?; let mut session = AsyncSession::<AsyncIoTcpStream>::connect(socket_addr, None).await?;
session.handshake().await?; session.handshake().await?;
@ -176,15 +178,12 @@ impl App {
return; return;
} }
let address = self.settings.address.parse(); if let Ok(addr) = self.settings.address.parse() {
if address.is_err() { let port = self.settings.port;
return;
}
let address = address.unwrap();
let port = self.settings.port;
let socket_addr = SocketAddrV4::new(address, port); let socket_addr = SocketAddrV4::new(addr, port);
self.start_connect(socket_addr, username.clone(), password.clone()); self.start_connect(socket_addr, username.clone(), password.clone());
}
} }
self.copy_texture = Some(cc.egui_ctx.load_texture( self.copy_texture = Some(cc.egui_ctx.load_texture(
@ -235,17 +234,19 @@ impl App {
return false; return false;
} }
fn handle_events(&mut self, _ctx: &egui::Context) { fn handle_events(&mut self, ctx: &egui::Context) {
use AsyncEvent::*; use AsyncEvent::*;
if let Ok(event) = self.rx.try_recv() { if let Ok(event) = self.rx.try_recv() {
ctx.request_repaint();
match event { match event {
Connect(result) => { Connect(result) => {
self.is_connecting = false; self.is_connecting = false;
match result { match result {
Ok(session) => { Ok(session) => {
self.session = Some(session); self.session = Some(session);
self.start_list_objects() self.start_list_objects();
self.start_keepalive();
} }
Err(err) => todo!("{}", err), Err(err) => todo!("{}", err),
} }
@ -253,6 +254,7 @@ impl App {
Disconnect(result) => { Disconnect(result) => {
self.is_disconnecting = false; self.is_disconnecting = false;
self.stop_keepalive();
if let Err(err) = result { if let Err(err) = result {
todo!("{}", err) todo!("{}", err)
@ -272,6 +274,27 @@ impl App {
} }
} }
fn start_keepalive(&mut self) {
if let Some(session) = &self.session {
if !session.authenticated() { return; }
let session = session.clone();
let handle = tokio::spawn(async move {
let next_keepalive = session.keepalive_send().await.unwrap();
tokio::time::sleep(Duration::from_secs(next_keepalive as u64)).await
});
self.keepalive_handle = Some(handle);
}
}
fn stop_keepalive(&mut self) {
if let Some(handle) = &self.keepalive_handle {
handle.abort();
self.keepalive_handle = None;
}
}
fn start_connect<A>(&mut self, socket_addr: A, username: String, password: String) fn start_connect<A>(&mut self, socket_addr: A, username: String, password: String)
where where
A: Into<SocketAddr>, A: Into<SocketAddr>,