added group messaging to tcp
parent
a1c6b1c81d
commit
4c8180dc17
|
|
@ -1,3 +1,5 @@
|
||||||
/target
|
/target
|
||||||
.vscode
|
.vscode
|
||||||
main
|
main
|
||||||
|
main.exe
|
||||||
|
main.pdb
|
||||||
|
|
|
||||||
68
src/main.rs
68
src/main.rs
|
|
@ -11,7 +11,9 @@ struct Client {
|
||||||
username: Arc<Mutex<String>>,
|
username: Arc<Mutex<String>>,
|
||||||
room: Arc<Mutex<Option<Arc<Room>>>>,
|
room: Arc<Mutex<Option<Arc<Room>>>>,
|
||||||
sender: SyncSender<Vec<u8>>,
|
sender: SyncSender<Vec<u8>>,
|
||||||
rooms_mutex: Arc<Mutex<HashMap<String,Arc<Room>>>>
|
rooms_mutex: Arc<Mutex<HashMap<String,Arc<Room>>>>,
|
||||||
|
clients_mutex: Arc<Mutex<HashMap<u32,Arc<Client>>>>,
|
||||||
|
groups: Arc<Mutex<HashMap<String,Vec<Arc<Client>>>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Room {
|
struct Room {
|
||||||
|
|
@ -133,7 +135,7 @@ fn read_join_message(stream: &mut TcpStream, client: &Arc<Client>){
|
||||||
|
|
||||||
//if the client is in a room, leave it
|
//if the client is in a room, leave it
|
||||||
|
|
||||||
let mut room = client.room.lock().unwrap();
|
let room = client.room.lock().unwrap();
|
||||||
if room.as_ref().is_some(){
|
if room.as_ref().is_some(){
|
||||||
client_leave_room(client, true);
|
client_leave_room(client, true);
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +158,7 @@ fn read_join_message(stream: &mut TcpStream, client: &Arc<Client>){
|
||||||
let mut clients = rooms[&room_name].clients.lock().unwrap();
|
let mut clients = rooms[&room_name].clients.lock().unwrap();
|
||||||
clients.insert(client.id,client.clone());
|
clients.insert(client.id,client.clone());
|
||||||
println!("Client {} joined {}",client.id,&room_name);
|
println!("Client {} joined {}",client.id,&room_name);
|
||||||
*room = Some(rooms[&room_name].clone());
|
|
||||||
//send a join message to everyone in the room
|
//send a join message to everyone in the room
|
||||||
for (_k,v) in clients.iter() {
|
for (_k,v) in clients.iter() {
|
||||||
send_client_join_message(v, client.id, &room_name);
|
send_client_join_message(v, client.id, &room_name);
|
||||||
|
|
@ -194,9 +196,23 @@ fn send_room_message(sender: &Arc<Client>, message: &Vec<u8>, include_sender: bo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//lock the clients in the room as well, because someone might leave the room in the middle...though, I suppose they'd have to lock the room to do it?
|
|
||||||
}
|
}
|
||||||
|
fn send_group_message(sender: &Arc<Client>, message: &Vec<u8>, group: &String){
|
||||||
|
|
||||||
|
let mut write_buf = vec![];
|
||||||
|
write_buf.push(3u8);
|
||||||
|
write_buf.extend_from_slice(&sender.id.to_be_bytes());
|
||||||
|
write_buf.extend_from_slice(&(message.len() as u32).to_be_bytes());
|
||||||
|
write_buf.extend_from_slice(message);
|
||||||
|
|
||||||
|
//get the list of client ids for this group
|
||||||
|
let groups = sender.groups.lock().unwrap();
|
||||||
|
let group = groups.get(group).unwrap();
|
||||||
|
for c in group {
|
||||||
|
c.sender.send(write_buf.clone()).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
fn read_send_message(stream: &mut TcpStream, client: &Arc<Client>, message_type: u8){
|
fn read_send_message(stream: &mut TcpStream, client: &Arc<Client>, message_type: u8){
|
||||||
//4 byte length, array
|
//4 byte length, array
|
||||||
//this is a message for everyone in the room (maybe)
|
//this is a message for everyone in the room (maybe)
|
||||||
|
|
@ -204,15 +220,45 @@ fn read_send_message(stream: &mut TcpStream, client: &Arc<Client>, message_type:
|
||||||
if message_type == 3 {
|
if message_type == 3 {
|
||||||
send_room_message(client,&to_send,false);
|
send_room_message(client,&to_send,false);
|
||||||
}else if message_type == 4 {
|
}else if message_type == 4 {
|
||||||
//everyone in my group
|
send_room_message(client,&to_send,true);
|
||||||
}else if message_type == 5 {
|
}else if message_type == 5 {
|
||||||
//everyone including me
|
let group = read_short_string(stream);
|
||||||
|
send_group_message(client,&to_send, &group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_group_message(stream: &mut TcpStream, client: &Arc<Client>){
|
||||||
|
let mut groups = client.groups.lock().unwrap();
|
||||||
|
let group = read_short_string(stream);
|
||||||
|
let id_bytes = read_vec(stream);
|
||||||
|
let num = id_bytes.len();
|
||||||
|
let clients = client.clients_mutex.lock().unwrap();
|
||||||
|
let mut group_clients = vec![];
|
||||||
|
for i in 0..num {
|
||||||
|
let mut slice = [0u8;4];
|
||||||
|
slice[0] = id_bytes[i];
|
||||||
|
slice[1] = id_bytes[i+1];
|
||||||
|
slice[2] = id_bytes[i+2];
|
||||||
|
slice[3] = id_bytes[i+3]; //probably a better way to do this
|
||||||
|
let id = u32::from_be_bytes(slice);
|
||||||
|
|
||||||
|
|
||||||
|
let client = clients.get(&id).unwrap();
|
||||||
|
group_clients.push(client.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the group if it exists
|
||||||
|
if groups.contains_key(&group) {
|
||||||
|
groups.remove(&group); //ensures the client references go away
|
||||||
|
}
|
||||||
|
|
||||||
|
groups.insert(group.clone(),group_clients);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fn client_read_thread(mut stream: TcpStream, mut client: Arc<Client>) {
|
fn client_read_thread(mut stream: TcpStream, mut client: Arc<Client>) {
|
||||||
let mut read_buf:[u8;1] = [0; 1];
|
let mut read_buf:[u8;1] = [0; 1];
|
||||||
//messages come through as a 4-bit type identifier, that can be one of 0 (login) 1 (get rooms), 2 (join/leave room) 3(send message others) 4(send message all) 5(send message group)
|
//messages come through as a 1 byte type identifier, that can be one of 0 (login) 1 (get rooms), 2 (join/leave room) 3 (send message to room), 4 (send message to room including me), 5 (send message to group), 6 (establish group)
|
||||||
loop {
|
loop {
|
||||||
|
|
||||||
//read exactly 1 byte
|
//read exactly 1 byte
|
||||||
|
|
@ -226,8 +272,10 @@ fn client_read_thread(mut stream: TcpStream, mut client: Arc<Client>) {
|
||||||
read_rooms_message(&mut stream, &mut client);
|
read_rooms_message(&mut stream, &mut client);
|
||||||
} else if t == 2 {
|
} else if t == 2 {
|
||||||
read_join_message(&mut stream, &mut client);
|
read_join_message(&mut stream, &mut client);
|
||||||
} else if t == 3 || t == 4 {
|
} else if t == 3 || t == 4 || t==5 {
|
||||||
read_send_message(&mut stream, &client, t);
|
read_send_message(&mut stream, &client, t);
|
||||||
|
} else if t == 6 {
|
||||||
|
read_group_message(&mut stream, &client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -262,7 +310,9 @@ fn handle_client(stream: TcpStream, client_id: u32, clients_mutex: Arc<Mutex<Has
|
||||||
logged_in: Arc::new(Mutex::new(false)),
|
logged_in: Arc::new(Mutex::new(false)),
|
||||||
room: Arc::new(Mutex::new(Option::None)),
|
room: Arc::new(Mutex::new(Option::None)),
|
||||||
sender: tx,
|
sender: tx,
|
||||||
rooms_mutex: rooms_mutex
|
rooms_mutex: rooms_mutex.clone(),
|
||||||
|
clients_mutex: clients_mutex.clone(),
|
||||||
|
groups: Arc::new(Mutex::new(HashMap::new()))
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue