naia_client_socket/backends/native/
socket.rs

1use naia_socket_shared::{parse_server_url, SocketConfig};
2
3use webrtc_unreliable_client::Socket as RTCSocket;
4
5use super::{packet_receiver::PacketReceiverImpl, packet_sender::PacketSenderImpl};
6use crate::{
7    backends::{native::runtime::get_runtime, socket::SocketTrait},
8    conditioned_packet_receiver::ConditionedPacketReceiver,
9    identity_receiver::IdentityReceiver,
10    packet_receiver::PacketReceiver,
11    packet_sender::PacketSender,
12    IdentityReceiverImpl,
13};
14
15/// A client-side socket which communicates with an underlying unordered &
16/// unreliable protocol
17pub struct Socket;
18
19impl Socket {
20    /// Connects to the given server address
21    pub fn connect(
22        server_session_url: &str,
23        config: &SocketConfig,
24    ) -> (
25        Box<dyn IdentityReceiver>,
26        Box<dyn PacketSender>,
27        Box<dyn PacketReceiver>,
28    ) {
29        Self::connect_inner(server_session_url, config, None, None)
30    }
31
32    /// Connects to the given server address with authentication
33    pub fn connect_with_auth(
34        server_session_url: &str,
35        config: &SocketConfig,
36        auth_bytes: Vec<u8>,
37    ) -> (
38        Box<dyn IdentityReceiver>,
39        Box<dyn PacketSender>,
40        Box<dyn PacketReceiver>,
41    ) {
42        Self::connect_inner(server_session_url, config, Some(auth_bytes), None)
43    }
44
45    /// Connects to the given server address with authentication
46    pub fn connect_with_auth_headers(
47        server_session_url: &str,
48        config: &SocketConfig,
49        auth_headers: Vec<(String, String)>,
50    ) -> (
51        Box<dyn IdentityReceiver>,
52        Box<dyn PacketSender>,
53        Box<dyn PacketReceiver>,
54    ) {
55        Self::connect_inner(server_session_url, config, None, Some(auth_headers))
56    }
57
58    /// Connects to the given server address with authentication
59    pub fn connect_with_auth_and_headers(
60        server_session_url: &str,
61        config: &SocketConfig,
62        auth_bytes: Vec<u8>,
63        auth_headers: Vec<(String, String)>,
64    ) -> (
65        Box<dyn IdentityReceiver>,
66        Box<dyn PacketSender>,
67        Box<dyn PacketReceiver>,
68    ) {
69        Self::connect_inner(
70            server_session_url,
71            config,
72            Some(auth_bytes),
73            Some(auth_headers),
74        )
75    }
76
77    /// Connects to the given server address
78    fn connect_inner(
79        server_session_url: &str,
80        config: &SocketConfig,
81        auth_bytes_opt: Option<Vec<u8>>,
82        auth_headers_opt: Option<Vec<(String, String)>>,
83    ) -> (
84        Box<dyn IdentityReceiver>,
85        Box<dyn PacketSender>,
86        Box<dyn PacketReceiver>,
87    ) {
88        let server_session_string = format!(
89            "{}{}",
90            parse_server_url(server_session_url),
91            config.rtc_endpoint_path.clone()
92        );
93        let conditioner_config = config.link_condition.clone();
94
95        let (socket, io) = RTCSocket::new();
96        get_runtime().spawn(async move {
97            socket
98                .connect(&server_session_string, auth_bytes_opt, auth_headers_opt)
99                .await;
100        });
101
102        // Setup Packet Sender
103        let packet_sender_impl = PacketSenderImpl::new(
104            io.addr_cell.clone(),
105            io.to_server_sender,
106            io.to_server_disconnect_sender,
107        );
108        let packet_sender: Box<dyn PacketSender> = Box::new(packet_sender_impl);
109
110        // Setup Packet Receiver
111        let packet_receiver_impl = PacketReceiverImpl::new(io.addr_cell, io.to_client_receiver);
112        let packet_receiver: Box<dyn PacketReceiver> = {
113            let inner_receiver = Box::new(packet_receiver_impl);
114            if let Some(config) = &conditioner_config {
115                Box::new(ConditionedPacketReceiver::new(inner_receiver, config))
116            } else {
117                inner_receiver
118            }
119        };
120
121        // Setup Identity Receiver
122        let identity_receiver_impl = IdentityReceiverImpl::new(io.to_client_id_receiver);
123        let identity_receiver: Box<dyn IdentityReceiver> = Box::new(identity_receiver_impl);
124
125        (identity_receiver, packet_sender, packet_receiver)
126    }
127}
128
129impl SocketTrait for Socket {
130    /// Connects to the given server address
131    fn connect(
132        server_session_url: &str,
133        config: &SocketConfig,
134    ) -> (
135        Box<dyn IdentityReceiver>,
136        Box<dyn PacketSender>,
137        Box<dyn PacketReceiver>,
138    ) {
139        return Self::connect(server_session_url, config);
140    }
141    /// Connects to the given server address with authentication
142    fn connect_with_auth(
143        server_session_url: &str,
144        config: &SocketConfig,
145        auth_bytes: Vec<u8>,
146    ) -> (
147        Box<dyn IdentityReceiver>,
148        Box<dyn PacketSender>,
149        Box<dyn PacketReceiver>,
150    ) {
151        return Self::connect_with_auth(server_session_url, config, auth_bytes);
152    }
153}