How to do it...

  1. In the folder bin, create a file called connection_handler.rs.

  2. Add the following code and run it with cargo run --bin connection_handler:

1 use std::sync::{Arc, RwLock};
2 use std::net::Ipv6Addr;
3 use std::collections::HashMap;
4 use std::{thread, time};
5 use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
6
7 // Client holds whatever state your client might have
8 struct Client {
9 ip: Ipv6Addr,
10 }
11
12 // ConnectionHandler manages a list of connections
13 // in a parallelly safe way
14 struct ConnectionHandler {
15 // The clients are identified by a unique key
16 clients: RwLock<HashMap<usize, Client>>,
17 next_id: AtomicUsize,
18 }
19
20 impl Client {
21 fn new(ip: Ipv6Addr) -> Self {
22 Client { ip }
23 }
24 }
25
26 impl ConnectionHandler {
27 fn new() -> Self {
28 ConnectionHandler {
29 clients: RwLock::new(HashMap::new()),
30 next_id: ATOMIC_USIZE_INIT,
31 }
32 }
33
34 fn client_count(&self) -> usize {
35 self.clients
36 .read()
37 .expect("Failed to lock clients for reading")
38 .len()
39 }
40
41 fn add_connection(&self, ip: Ipv6Addr) -> usize {
42 let last = self.next_id.fetch_add(1, Ordering::SeqCst);
43 self.clients
44 .write()
45 .expect("Failed to lock clients for writing")
46 .insert(last, Client::new(ip));
47 last
48 }
49
50 fn remove_connection(&self, id: usize) -> Option<()> {
51 self.clients
52 .write()
53 .expect("Failed to lock clients for writing")
54 .remove(&id)
55 .and(Some(()))
56 }
57 }

Using our connection handler by simulating connecting and disconnecting clients:

59 fn main() {
60 let connections = Arc::new(ConnectionHandler::new());
61
62 // the connector thread will add a new connection every now and
then
63 let connector = {
64 let connections = connections.clone();
65 let dummy_ip = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a,
0x2ff);
66 let ten_millis = time::Duration::from_millis(10);
67 thread::spawn(move || {
68 for _ in 0..20 {
69 connections.add_connection(dummy_ip);
70 thread::sleep(ten_millis);
71 }
72 })
73 };
74
75 // the disconnector thread will remove the third connection at
some point
76 let disconnector = {
77 let connections = connections.clone();
78 let fifty_millis = time::Duration::from_millis(50);
79 thread::spawn(move || {
80 thread::sleep(fifty_millis);
81 connections.remove_connection(2);
82 })
83 };
84
85 // The main thread will print the active connections in a short
interval
86 let five_millis = time::Duration::from_millis(5);
87 for _ in 0..40 {
88 let count = connections.client_count();
89 println!("Active connections: {}", count);
90 thread::sleep(five_millis);
91 }
92
93 connector.join().expect("The connector thread panicked");
94 disconnector
95 .join()
96 .expect("The disconnector thread panicked");
97 }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.173.242