1mod actor;
4pub mod actor_handle;
5pub mod event;
6
7use crate::client::actor_handle::ActorHandle;
8use crate::client::event::Event;
9use crate::message_types::MessageTypes;
10use futures::channel::mpsc;
11use tokio::net::TcpStream;
12use tokio::net::UdpSocket;
13
14#[derive(thiserror::Error, Debug)]
16pub enum ConnectError {
17 #[error("IO Error")]
19 Io(#[from] ::std::io::Error),
20
21 #[error("Unknown host {}", host)]
23 UnknownHost {
24 host: String,
26 },
27}
28
29#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct Status {
34 pub latest_udp_heartbeat: Option<std::time::Instant>,
36}
37
38pub async fn connect<M: MessageTypes>(server_host: &str) -> Result<(ActorHandle<M>, futures::channel::mpsc::Receiver<Event<M>>), ConnectError> {
40 log::info!("Resolving host {server_host}...");
42 let mut server_addr_iter = tokio::net::lookup_host(server_host).await?;
43 let server_addr = server_addr_iter.next().ok_or_else(|| ConnectError::UnknownHost {
44 host: server_host.to_owned(),
45 })?;
46 log::info!("OK: {server_host} resolved to {server_addr}");
47
48 log::info!("Connecting TCP stream...");
49 let tcp_stream = TcpStream::connect(&server_addr).await?;
50 log::info!("OK: Connected TCP stream");
51 log::info!("Getting TCP stream local address...");
52 let local_addr = tcp_stream.local_addr()?;
53 log::info!("OK: TCP stream local address {local_addr}");
54 log::info!("Binding UDP socket at {local_addr}...");
55 let udp_socket = UdpSocket::bind(local_addr).await?;
56 log::info!("OK: Bound UDP socket");
57 log::info!("Setting default destination for UDP socket...");
58 udp_socket.connect(&server_addr).await?;
59 log::info!("OK: Set default destination for UDP socket");
60
61 let (actor_msg_sender, actor_msg_receiver) = mpsc::channel::<actor::Message<M>>(32);
62 let (event_sender, event_receiver) = mpsc::channel::<Event<M>>(128);
63
64 let join_handle = tokio::spawn(actor::actor(actor_msg_receiver, event_sender, tcp_stream, udp_socket, server_addr));
65 let actor_handle = ActorHandle::new(join_handle, actor_msg_sender);
66
67 Ok((actor_handle, event_receiver))
68}