]> git.lizzy.rs Git - mt_rudp.git/blob - src/client.rs
Use channels
[mt_rudp.git] / src / client.rs
1 use super::*;
2 use async_trait::async_trait;
3 use std::{io, sync::Arc};
4 use tokio::{
5     net,
6     sync::{mpsc, watch},
7 };
8
9 #[derive(Debug)]
10 pub struct UdpCltSender(Arc<net::UdpSocket>);
11
12 #[derive(Debug)]
13 pub struct UdpCltReceiver(Arc<net::UdpSocket>);
14
15 #[async_trait]
16 impl UdpSender for UdpCltSender {
17     async fn send(&self, data: &[u8]) -> io::Result<()> {
18         self.0.send(data).await?;
19         Ok(())
20     }
21 }
22
23 #[async_trait]
24 impl UdpReceiver for UdpCltReceiver {
25     async fn recv(&mut self) -> io::Result<Vec<u8>> {
26         let mut buffer = Vec::new();
27         buffer.resize(UDP_PKT_SIZE, 0);
28
29         let len = self.0.recv(&mut buffer).await?;
30         buffer.truncate(len);
31
32         Ok(buffer)
33     }
34 }
35
36 #[derive(Debug)]
37 pub struct CltReceiver(mpsc::UnboundedReceiver<Result<Pkt<'static>, Error>>);
38
39 impl CltReceiver {
40     pub async fn recv_rudp(&mut self) -> Option<Result<Pkt<'static>, Error>> {
41         self.0.recv().await
42     }
43 }
44
45 pub type CltSender = Arc<Sender<UdpCltSender>>;
46 pub type CltWorker = Worker<UdpCltSender, UdpCltReceiver>;
47
48 pub async fn connect(addr: &str) -> io::Result<(CltSender, CltReceiver, CltWorker)> {
49     let sock = Arc::new(net::UdpSocket::bind("0.0.0.0:0").await?);
50     sock.connect(addr).await?;
51
52     let (close_tx, close_rx) = watch::channel(false);
53     let (pkt_tx, pkt_rx) = mpsc::unbounded_channel();
54
55     let sender = Sender::new(
56         UdpCltSender(Arc::clone(&sock)),
57         close_tx,
58         PeerID::Srv as u16,
59         PeerID::Nil as u16,
60     );
61
62     Ok((
63         Arc::clone(&sender),
64         CltReceiver(pkt_rx),
65         Worker::new(UdpCltReceiver(sock), close_rx, sender, pkt_tx),
66     ))
67 }