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
115
116
117
118
119
120
121
122
123
use chashmap::{CHashMap, ReadGuard};
use log::{debug};
use crate::socketio::InternalMessage;
use tokio::sync::broadcast::Sender;
lazy_static! {
static ref ROOMS: CHashMap<String, Vec<ChannelPair>> = CHashMap::new();
}
#[derive(Clone)]
pub struct ChannelPair {
sid: String,
sender: Sender<InternalMessage>,
}
impl ChannelPair {
pub fn new(sid: &str, sender: Sender<InternalMessage>) -> Self {
ChannelPair {
sid: sid.to_string(),
sender,
}
}
pub fn send(&self, message: InternalMessage) {
let _ = self.sender.send(message);
}
pub fn sid(&self) -> &str {
&self.sid
}
}
pub fn join_channel_to_room(room_id: &str, channel_pair: ChannelPair) {
let mut connected_sockets = match ROOMS.remove(room_id) {
Some(val) => val,
None => Vec::new(),
};
let mut exist = false;
for socket in &connected_sockets {
if socket.sid() == channel_pair.sid() {
debug!("ROOMS: socketid {} doesn't join room {}, this socketid already exist in the room.", channel_pair.sid(), room_id);
exist = true;
break;
}
}
if !exist {
debug!("ROOMS: socketid {} joined room {}, room len = {}.", channel_pair.sid(), room_id, connected_sockets.len() + 1);
connected_sockets.push(channel_pair);
}
ROOMS.insert(room_id.to_string(), connected_sockets);
}
pub fn remove_socket_from_room(room_id: &str, sid: &str) {
let mut connected_sockets = match ROOMS.remove(room_id) {
Some(val) => val,
None => Vec::new(),
};
for i in 0..connected_sockets.len() {
let socket = connected_sockets.get(i).unwrap();
if socket.sid == sid {
connected_sockets.remove(i);
debug!("ROOMS: socketid {} leave room {}, room len = {}.", sid, room_id, connected_sockets.len());
break;
}
}
if connected_sockets.len() > 0 {
debug!("ROOMS: {} sockets insert back into ROOMS {}.", connected_sockets.len(), room_id);
ROOMS.insert(room_id.to_string(), connected_sockets);
}
}
pub fn get_sockets_for_room(room_id: &str) -> Option<ReadGuard<String, Vec<ChannelPair>>> {
ROOMS.get(room_id)
}
pub fn get_sockets_number_for_room(room_id: &str) -> usize {
ROOMS.get(room_id).map(|channels| channels.len()).unwrap_or(0)
}
pub fn print_sockets_for_room(room_id: &str) {
match ROOMS.get(room_id) {
Some(sockets) => {
debug!("ROOMS: room {} containt sockets number = {}.", room_id, sockets.len());
}
None => {
debug!("ROOMS: no socket in room {}.", room_id);
}
}
}
pub fn get_rooms_count() -> usize {
ROOMS.len()
}