persistence + proper disconnect
This commit is contained in:
@@ -9,6 +9,7 @@ use quinn::{
|
||||
use std::{
|
||||
net::{Ipv6Addr, SocketAddr, SocketAddrV6, ToSocketAddrs},
|
||||
sync::Arc,
|
||||
thread::JoinHandle,
|
||||
time::Duration,
|
||||
};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
@@ -21,24 +22,69 @@ pub struct ConnectInfo {
|
||||
pub username: String,
|
||||
}
|
||||
|
||||
pub fn connect(handle: AppHandle, info: ConnectInfo) {
|
||||
pub struct NetHandle {
|
||||
pub send: NetSender,
|
||||
pub thread: JoinHandle<()>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub enum NetState {
|
||||
#[default]
|
||||
None,
|
||||
Connecting(JoinHandle<()>),
|
||||
Connected(NetHandle),
|
||||
}
|
||||
|
||||
impl NetState {
|
||||
pub fn take_connection(&mut self) -> Option<NetHandle> {
|
||||
match self.take() {
|
||||
NetState::Connected(net_handle) => Some(net_handle),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connection(&self) -> Option<&NetHandle> {
|
||||
match self {
|
||||
NetState::Connected(net_handle) => Some(net_handle),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take(&mut self) -> Self {
|
||||
std::mem::replace(self, Self::None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn connect(handle: AppHandle, info: ConnectInfo) -> JoinHandle<()> {
|
||||
std::thread::spawn(move || {
|
||||
if let Err(msg) = connect_the(handle.clone(), info) {
|
||||
handle.send(ClientEvent::Err(msg));
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
type NetResult<T> = Result<T, String>;
|
||||
|
||||
type MsgPayload = ClientMsg;
|
||||
#[derive(Clone)]
|
||||
pub struct NetSender {
|
||||
send: UnboundedSender<MsgPayload>,
|
||||
send: UnboundedSender<NetCtrlMsg>,
|
||||
}
|
||||
|
||||
pub enum NetCtrlMsg {
|
||||
Send(ClientMsg),
|
||||
Exit,
|
||||
}
|
||||
|
||||
impl From<ClientMsg> for NetCtrlMsg {
|
||||
fn from(value: ClientMsg) -> Self {
|
||||
Self::Send(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl NetSender {
|
||||
pub fn send(&self, msg: ClientMsg) {
|
||||
let _ = self.send.send(msg);
|
||||
pub fn send(&self, msg: impl Into<NetCtrlMsg>) {
|
||||
let _ = self.send.send(msg.into());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +114,7 @@ impl NetSender {
|
||||
// .map_err(|e| format!("failed to connect: {}", e))
|
||||
// }
|
||||
|
||||
async fn connection_no_cert(addr: SocketAddr) -> NetResult<Connection> {
|
||||
async fn connection_no_cert(addr: SocketAddr) -> NetResult<(Endpoint, Connection)> {
|
||||
let mut endpoint = Endpoint::client(CLIENT_SOCKET).map_err(|e| e.to_string())?;
|
||||
|
||||
let quic = QuicClientConfig::try_from(
|
||||
@@ -91,16 +137,17 @@ async fn connection_no_cert(addr: SocketAddr) -> NetResult<Connection> {
|
||||
endpoint.set_default_client_config(config);
|
||||
|
||||
// connect to server
|
||||
endpoint
|
||||
let con = endpoint
|
||||
.connect(addr, SERVER_NAME)
|
||||
.map_err(|e| e.to_string())?
|
||||
.await
|
||||
.map_err(|e| e.to_string())
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok((endpoint, con))
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn connect_the(handle: AppHandle, info: ConnectInfo) -> NetResult<()> {
|
||||
let (send, mut ui_recv) = tokio::sync::mpsc::unbounded_channel::<MsgPayload>();
|
||||
let (send, mut ui_recv) = tokio::sync::mpsc::unbounded_channel::<NetCtrlMsg>();
|
||||
|
||||
let addr = info
|
||||
.ip
|
||||
@@ -108,7 +155,7 @@ async fn connect_the(handle: AppHandle, info: ConnectInfo) -> NetResult<()> {
|
||||
.map_err(|e| e.to_string())?
|
||||
.next()
|
||||
.ok_or("no addresses found".to_string())?;
|
||||
let conn = connection_no_cert(addr).await?;
|
||||
let (endpoint, conn) = connection_no_cert(addr).await?;
|
||||
let conn_ = conn.clone();
|
||||
|
||||
handle.send(ClientEvent::Connect {
|
||||
@@ -120,9 +167,18 @@ async fn connect_the(handle: AppHandle, info: ConnectInfo) -> NetResult<()> {
|
||||
tokio::spawn(recv_uni(conn_, recv.into()));
|
||||
|
||||
while let Some(msg) = ui_recv.recv().await {
|
||||
if send_uni(&conn, msg).await.is_err() {
|
||||
println!("disconnected from server");
|
||||
break;
|
||||
match msg {
|
||||
NetCtrlMsg::Send(msg) => {
|
||||
if send_uni(&conn, msg).await.is_err() {
|
||||
println!("disconnected from server");
|
||||
break;
|
||||
}
|
||||
}
|
||||
NetCtrlMsg::Exit => {
|
||||
conn.close(quinn::VarInt::from_u32(0), &[]);
|
||||
endpoint.wait_idle().await;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user