1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
extern crate log;
use std::{
net::UdpSocket,
sync::{Arc, Mutex},
};
use log::info;
use naia_socket_shared::{parse_server_url, url_to_socket_addr, SocketConfig};
use crate::{
conditioned_packet_receiver::ConditionedPacketReceiver,
io::Io,
packet_receiver::{PacketReceiver, PacketReceiverTrait},
};
use super::{packet_receiver::PacketReceiverImpl, packet_sender::PacketSender};
pub struct Socket {
config: SocketConfig,
io: Option<Io>,
}
impl Socket {
pub fn new(config: &SocketConfig) -> Self {
Socket {
config: config.clone(),
io: None,
}
}
pub fn connect(&mut self, server_session_url: &str) {
if self.io.is_some() {
panic!("Socket already listening!");
}
let server_url = parse_server_url(server_session_url);
let server_socket_addr = url_to_socket_addr(&server_url);
let client_ip_address =
find_my_ip_address().expect("cannot find host's current IP address");
let socket = Arc::new(Mutex::new(UdpSocket::bind((client_ip_address, 0)).unwrap()));
socket
.as_ref()
.lock()
.unwrap()
.set_nonblocking(true)
.expect("can't set socket to non-blocking!");
let local_addr = socket.as_ref().lock().unwrap().local_addr().unwrap();
let packet_sender = PacketSender::new(server_socket_addr, socket.clone());
let conditioner_config = self.config.link_condition.clone();
let receiver: Box<dyn PacketReceiverTrait> = {
let inner_receiver =
Box::new(PacketReceiverImpl::new(server_socket_addr, socket.clone()));
if let Some(config) = &conditioner_config {
Box::new(ConditionedPacketReceiver::new(inner_receiver, config))
} else {
inner_receiver
}
};
info!("UDP client listening on socket: {}", local_addr);
self.io = Some(Io {
packet_sender: packet_sender.clone(),
packet_receiver: PacketReceiver::new(receiver),
});
}
pub fn packet_sender(&self) -> PacketSender {
return self
.io
.as_ref()
.expect("Socket is not connected yet! Call Socket.connect() before this.")
.packet_sender
.clone();
}
pub fn packet_receiver(&self) -> PacketReceiver {
return self
.io
.as_ref()
.expect("Socket is not connected yet! Call Socket.connect() before this.")
.packet_receiver
.clone();
}
}
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
pub fn find_my_ip_address() -> Option<IpAddr> {
let ip = local_ipaddress::get().unwrap_or_default();
if let Ok(addr) = ip.parse::<Ipv4Addr>() {
return Some(IpAddr::V4(addr));
} else if let Ok(addr) = ip.parse::<Ipv6Addr>() {
return Some(IpAddr::V6(addr));
} else {
return None;
}
}