tweak to use serde for message json serialization

This commit is contained in:
Peter Hart 2020-05-04 23:53:09 -04:00
parent b24c933e6c
commit 2c72f35887
2 changed files with 50 additions and 55 deletions

View File

@ -148,7 +148,7 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsChatSession {
"/join" => {
if v.len() == 2 {
self.room = v[1].to_owned();
self.addr.do_send(server::Join {
self.addr.do_send(server::ChatMessage::Join {
id: self.id,
name: self.room.clone(),
});
@ -174,7 +174,7 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsChatSession {
m.to_owned()
};
// send message to chat server
self.addr.do_send(server::ClientMessage {
self.addr.do_send(server::ChatMessage::ClientMessage {
id: self.id,
msg,
room: self.room.clone(),

View File

@ -1,10 +1,10 @@
//! `ChatServer` is an actor. It maintains list of connection client session.
//! And manages available rooms. Peers send messages to other peers in same
//! room through `ChatServer`.
use actix::prelude::*;
use rand::{self, rngs::ThreadRng, Rng};
use serde::*;
use std::collections::{HashMap, HashSet};
/// Chat server sends this messages to session
@ -29,33 +29,32 @@ pub struct Disconnect {
}
/// Send message to specific room
#[derive(Message)]
#[derive(Message, Serialize, Deserialize)]
#[rtype(result = "()")]
pub struct ClientMessage {
/// Id of the client session
pub id: usize,
/// Peer message
pub msg: String,
/// Room name
pub room: String,
#[serde(tag = "type")]
pub enum ChatMessage {
ClientMessage {
/// Id of the client session
id: usize,
/// Peer message
msg: String,
/// Room name
room: String,
},
Join {
/// Client id
id: usize,
/// Room name
name: String,
},
}
/// List of available rooms
#[derive(Message)]
#[rtype(result = "Vec<String>")]
pub struct ListRooms;
impl actix::Message for ListRooms {
type Result = Vec<String>;
}
/// Join room, if room does not exists create new one.
#[derive(Message)]
#[rtype(result = "()")]
pub struct Join {
/// Client id
pub id: usize,
/// Room name
pub name: String,
}
/// `ChatServer` manages chat rooms and responsible for coordinating chat
/// session. implementation is super primitive
@ -154,11 +153,36 @@ impl Handler<Disconnect> for ChatServer {
}
/// Handler for Message message.
impl Handler<ClientMessage> for ChatServer {
impl Handler<ChatMessage> for ChatServer {
type Result = ();
fn handle(&mut self, msg: ClientMessage, _: &mut Context<Self>) {
self.send_message(&msg.room, msg.msg.as_str(), msg.id);
fn handle(&mut self, msg: ChatMessage, _: &mut Context<Self>) {
match msg {
ChatMessage::ClientMessage { room, msg, id } => {
self.send_message(&room, msg.as_str(), id)
}
ChatMessage::Join { id, name } => {
let mut rooms = Vec::new();
// remove session from all rooms
for (n, sessions) in &mut self.rooms {
if sessions.remove(&id) {
rooms.push(n.to_owned());
}
}
// send message to other users
for room in rooms {
self.send_message(&room, "Someone disconnected", 0);
}
self.rooms
.entry(name.clone())
.or_insert(HashSet::new())
.insert(id);
self.send_message(&name, "Someone connected", id);
}
}
}
}
@ -176,32 +200,3 @@ impl Handler<ListRooms> for ChatServer {
MessageResult(rooms)
}
}
/// Join room, send disconnect message to old room
/// send join message to new room
impl Handler<Join> for ChatServer {
type Result = ();
fn handle(&mut self, msg: Join, _: &mut Context<Self>) {
let Join { id, name } = msg;
let mut rooms = Vec::new();
// remove session from all rooms
for (n, sessions) in &mut self.rooms {
if sessions.remove(&id) {
rooms.push(n.to_owned());
}
}
// send message to other users
for room in rooms {
self.send_message(&room, "Someone disconnected", 0);
}
self.rooms
.entry(name.clone())
.or_insert(HashSet::new())
.insert(id);
self.send_message(&name, "Someone connected", id);
}
}