naia_server_socket/
socket.rs

1use std::net::SocketAddr;
2
3use smol::channel;
4
5use naia_socket_shared::{IdentityToken, SocketConfig};
6
7use super::{
8    async_socket::Socket as AsyncSocket,
9    auth_receiver::{AuthReceiver, AuthReceiverImpl},
10    auth_sender::{AuthSender, AuthSenderImpl},
11    conditioned_packet_receiver::ConditionedPacketReceiverImpl,
12    executor,
13    packet_receiver::{PacketReceiver, PacketReceiverImpl},
14    packet_sender::{PacketSender, PacketSenderImpl},
15    server_addrs::ServerAddrs,
16    NaiaServerSocketError,
17};
18
19/// Used to send packets from the Server Socket
20#[allow(dead_code)]
21pub trait SocketTrait {
22    fn listen(
23        server_addrs: &ServerAddrs,
24        config: &SocketConfig,
25    ) -> (Box<dyn PacketSender>, Box<dyn PacketReceiver>);
26}
27
28/// Socket is able to send and receive messages from remote Clients
29pub struct Socket;
30
31impl Socket {
32    /// Listens on the Socket for incoming communication from Clients
33    pub fn listen(
34        server_addrs: &ServerAddrs,
35        config: &SocketConfig,
36    ) -> (Box<dyn PacketSender>, Box<dyn PacketReceiver>) {
37        let (from_client_receiver, sender_receiver) =
38            Self::setup_receiver_loop(server_addrs, config, None, None);
39
40        Self::setup_sender_loop(config, from_client_receiver, sender_receiver)
41    }
42    /// Listens on the Socket for incoming communication from Clients
43    pub fn listen_with_auth(
44        server_addrs: &ServerAddrs,
45        config: &SocketConfig,
46    ) -> (
47        Box<dyn AuthSender>,
48        Box<dyn AuthReceiver>,
49        Box<dyn PacketSender>,
50        Box<dyn PacketReceiver>,
51    ) {
52        let (from_client_auth_sender, from_client_auth_receiver) = channel::unbounded();
53        let (to_session_all_auth_sender, to_session_all_auth_receiver) = channel::unbounded();
54        let from_client_auth_sender = Some(from_client_auth_sender);
55        let to_session_all_auth_receiver = Some(to_session_all_auth_receiver);
56
57        let (from_client_receiver, sender_receiver) = Self::setup_receiver_loop(
58            server_addrs,
59            config,
60            from_client_auth_sender,
61            to_session_all_auth_receiver,
62        );
63
64        let (packet_sender, packet_receiver) =
65            Self::setup_sender_loop(config, from_client_receiver, sender_receiver);
66
67        // Setup Sender
68        let auth_sender_impl = AuthSenderImpl::new(to_session_all_auth_sender);
69
70        let auth_sender: Box<dyn AuthSender> = Box::new(auth_sender_impl);
71
72        // Setup Receiver
73        let auth_receiver: Box<dyn AuthReceiver> =
74            Box::new(AuthReceiverImpl::new(from_client_auth_receiver));
75
76        (auth_sender, auth_receiver, packet_sender, packet_receiver)
77    }
78
79    fn setup_receiver_loop(
80        server_addrs: &ServerAddrs,
81        config: &SocketConfig,
82        from_client_auth_sender: Option<
83            channel::Sender<Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>>,
84        >,
85        to_session_all_auth_receiver: Option<
86            channel::Receiver<(SocketAddr, Option<IdentityToken>)>,
87        >,
88    ) -> (
89        channel::Receiver<Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>>,
90        channel::Receiver<channel::Sender<(SocketAddr, Box<[u8]>)>>,
91    ) {
92        // Set up receiver loop
93        let (from_client_sender, from_client_receiver) = channel::unbounded();
94        let (sender_sender, sender_receiver) = channel::unbounded();
95
96        let server_addrs_clone = server_addrs.clone();
97        let config_clone = config.clone();
98
99        executor::spawn(async move {
100            // Create async socket
101            let mut async_socket = AsyncSocket::listen(
102                server_addrs_clone,
103                config_clone,
104                from_client_auth_sender,
105                to_session_all_auth_receiver,
106            )
107            .await;
108
109            sender_sender.send(async_socket.sender()).await.unwrap();
110            //TODO: handle result..
111
112            loop {
113                let out_message = async_socket.receive().await;
114                from_client_sender.send(out_message).await.unwrap();
115                //TODO: handle result..
116            }
117        })
118        .detach();
119
120        (from_client_receiver, sender_receiver)
121    }
122
123    fn setup_sender_loop(
124        config: &SocketConfig,
125        from_client_receiver: channel::Receiver<
126            Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>,
127        >,
128        sender_receiver: channel::Receiver<channel::Sender<(SocketAddr, Box<[u8]>)>>,
129    ) -> (Box<dyn PacketSender>, Box<dyn PacketReceiver>) {
130        // Set up sender loop
131        let (to_client_sender, to_client_receiver) = channel::unbounded();
132
133        executor::spawn(async move {
134            // Create async socket
135            let async_sender = sender_receiver.recv().await.unwrap();
136
137            loop {
138                if let Ok(msg) = to_client_receiver.recv().await {
139                    async_sender.send(msg).await.unwrap();
140                    //TODO: handle result..
141                }
142            }
143        })
144        .detach();
145
146        let conditioner_config = config.link_condition.clone();
147
148        // Setup Sender
149        let packet_sender_impl = PacketSenderImpl::new(to_client_sender);
150
151        let packet_sender: Box<dyn PacketSender> = Box::new(packet_sender_impl);
152
153        // Setup Receiver
154        let packet_receiver: Box<dyn PacketReceiver> = match &conditioner_config {
155            Some(config) => Box::new(ConditionedPacketReceiverImpl::new(
156                from_client_receiver,
157                config,
158            )),
159            None => Box::new(PacketReceiverImpl::new(from_client_receiver)),
160        };
161
162        return (packet_sender, packet_receiver);
163    }
164}
165
166impl SocketTrait for Socket {
167    fn listen(
168        server_addrs: &ServerAddrs,
169        config: &SocketConfig,
170    ) -> (Box<dyn PacketSender>, Box<dyn PacketReceiver>) {
171        return Socket::listen(server_addrs, config);
172    }
173}