mirror of
https://codeberg.org/JasterV/chat-rooms-actix.git
synced 2026-04-27 02:15:42 +00:00
refactor
This commit is contained in:
parent
76f3a81d07
commit
7bef1322a3
8 changed files with 45 additions and 35 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -125,6 +125,7 @@ dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-actors",
|
"actix-web-actors",
|
||||||
"derive_more",
|
"derive_more",
|
||||||
|
"serde_json",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,4 @@ actix-web = "3"
|
||||||
actix-web-actors = "3.0.0"
|
actix-web-actors = "3.0.0"
|
||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||||
derive_more = "0.99.11"
|
derive_more = "0.99.11"
|
||||||
|
serde_json = "1.0.64"
|
||||||
|
|
@ -3,14 +3,14 @@ use std::collections::{HashMap, HashSet};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::messages::{
|
use crate::messages::{
|
||||||
chat_server::{ClientMessage, Connect, Disconnect, JoinRoom},
|
chat_server::{ClientMessage, Connect, CreateRoom, Disconnect, JoinRoom},
|
||||||
chat_session::Message,
|
chat_session::Message,
|
||||||
};
|
};
|
||||||
use crate::models::SessionId;
|
use crate::models::{RoomId, SessionId};
|
||||||
|
|
||||||
pub struct ChatServer {
|
pub struct ChatServer {
|
||||||
sessions: HashMap<SessionId, Recipient<Message>>,
|
sessions: HashMap<SessionId, Recipient<Message>>,
|
||||||
rooms: HashMap<String, HashSet<SessionId>>,
|
rooms: HashMap<RoomId, HashSet<SessionId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChatServer {
|
impl ChatServer {
|
||||||
|
|
@ -21,7 +21,7 @@ impl ChatServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_message(&self, room: &str, message: &str, skip_id: &Uuid) {
|
pub fn send_message(&self, room: &Uuid, message: &str, skip_id: &Uuid) {
|
||||||
self.rooms.get(room).map(|sessions| {
|
self.rooms.get(room).map(|sessions| {
|
||||||
sessions.iter().for_each(|id| {
|
sessions.iter().for_each(|id| {
|
||||||
if id != skip_id {
|
if id != skip_id {
|
||||||
|
|
@ -68,10 +68,25 @@ impl Handler<ClientMessage> for ChatServer {
|
||||||
|
|
||||||
fn handle(&mut self, msg: ClientMessage, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: ClientMessage, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
let ClientMessage { session, room, msg } = msg;
|
let ClientMessage { session, room, msg } = msg;
|
||||||
|
|
||||||
self.send_message(&room, &msg, &session);
|
self.send_message(&room, &msg, &session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Handler<CreateRoom> for ChatServer {
|
||||||
|
type Result = MessageResult<CreateRoom>;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: CreateRoom, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
|
let CreateRoom { session } = msg;
|
||||||
|
let room_id = RoomId::new_v4();
|
||||||
|
self.rooms.insert(
|
||||||
|
room_id,
|
||||||
|
vec![session].into_iter().collect::<HashSet<Uuid>>(),
|
||||||
|
);
|
||||||
|
MessageResult(room_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Handler<JoinRoom> for ChatServer {
|
impl Handler<JoinRoom> for ChatServer {
|
||||||
type Result = ();
|
type Result = ();
|
||||||
fn handle(
|
fn handle(
|
||||||
|
|
@ -93,10 +108,8 @@ impl Handler<JoinRoom> for ChatServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
self.rooms
|
self.rooms
|
||||||
.entry(room.clone())
|
.get_mut(&room)
|
||||||
.or_insert_with(HashSet::new)
|
.map(|sessions| sessions.insert(session))
|
||||||
.insert(session);
|
.map(|_| self.send_message(&room, "Someone connected", &session));
|
||||||
|
|
||||||
self.send_message(&room, "Someone connected", &session);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@ use crate::{
|
||||||
actors::chat_server::ChatServer,
|
actors::chat_server::ChatServer,
|
||||||
commands::Command,
|
commands::Command,
|
||||||
messages::{
|
messages::{
|
||||||
chat_server::{ClientMessage, Connect, Disconnect, JoinRoom},
|
chat_server::{ClientMessage, Connect, Disconnect},
|
||||||
chat_session::Message,
|
chat_session::Message,
|
||||||
},
|
},
|
||||||
|
models::{RoomId, SessionId},
|
||||||
};
|
};
|
||||||
use actix::{
|
use actix::{
|
||||||
fut, ActorContext, ActorFuture, ContextFutureSpawner, Handler, Running, StreamHandler,
|
fut, ActorContext, ActorFuture, ContextFutureSpawner, Handler, Running, StreamHandler,
|
||||||
|
|
@ -14,11 +15,10 @@ use actix::{
|
||||||
};
|
};
|
||||||
use actix::{Actor, Addr, AsyncContext};
|
use actix::{Actor, Addr, AsyncContext};
|
||||||
use actix_web_actors::ws::{self, WebsocketContext};
|
use actix_web_actors::ws::{self, WebsocketContext};
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
pub struct WsChatSession {
|
pub struct WsChatSession {
|
||||||
pub id: Option<Uuid>,
|
pub id: Option<SessionId>,
|
||||||
pub room: Option<String>,
|
pub room: Option<RoomId>,
|
||||||
pub addr: Addr<ChatServer>,
|
pub addr: Addr<ChatServer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,15 +31,8 @@ impl WsChatSession {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute(&self, cmd: Command, ctx: &mut WebsocketContext<Self>) {
|
pub fn execute(&self, cmd: Command, _ctx: &mut WebsocketContext<Self>) {
|
||||||
match cmd {
|
match cmd {
|
||||||
Command::Join(name) => {
|
|
||||||
self.addr.do_send(JoinRoom {
|
|
||||||
session: self.id.unwrap().clone(),
|
|
||||||
room: name,
|
|
||||||
});
|
|
||||||
ctx.text("Joined!");
|
|
||||||
}
|
|
||||||
Command::Msg(msg) => {
|
Command::Msg(msg) => {
|
||||||
self.addr.do_send(ClientMessage {
|
self.addr.do_send(ClientMessage {
|
||||||
session: self.id.clone().unwrap(),
|
session: self.id.clone().unwrap(),
|
||||||
|
|
@ -100,6 +93,7 @@ impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for WsChatSession {
|
||||||
};
|
};
|
||||||
|
|
||||||
match msg {
|
match msg {
|
||||||
|
// TODO: Deserialize string to json first, then check action type
|
||||||
ws::Message::Text(msg) => match Command::from_str(&msg) {
|
ws::Message::Text(msg) => match Command::from_str(&msg) {
|
||||||
Ok(cmd) => self.execute(cmd, ctx),
|
Ok(cmd) => self.execute(cmd, ctx),
|
||||||
Err(err) => ctx.text(err.to_string()),
|
Err(err) => ctx.text(err.to_string()),
|
||||||
|
|
|
||||||
|
|
@ -9,21 +9,14 @@ pub struct CommandError {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Command {
|
pub enum Command {
|
||||||
Join(String),
|
|
||||||
Msg(String),
|
Msg(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: IMPLEMENT MORE COMMANDS
|
||||||
impl FromStr for Command {
|
impl FromStr for Command {
|
||||||
type Err = CommandError;
|
type Err = CommandError;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
let words: Vec<&str> = s.trim().split_whitespace().into_iter().collect();
|
|
||||||
let first = words.first().map(|&v| v).unwrap_or("");
|
|
||||||
if first == "/join" {
|
|
||||||
let name = words.last().map(|&v| v).unwrap_or("");
|
|
||||||
Ok(Command::Join(name.into()))
|
|
||||||
} else {
|
|
||||||
Ok(Command::Msg(s.into()))
|
Ok(Command::Msg(s.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,28 @@
|
||||||
use super::chat_session::Message;
|
|
||||||
use crate::models::SessionId;
|
|
||||||
use actix::{Message as ActixMessage, Recipient};
|
use actix::{Message as ActixMessage, Recipient};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::models::{RoomId, SessionId};
|
||||||
|
|
||||||
|
use super::chat_session::Message;
|
||||||
|
|
||||||
#[derive(ActixMessage)]
|
#[derive(ActixMessage)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct ClientMessage {
|
pub struct ClientMessage {
|
||||||
pub session: SessionId,
|
pub session: SessionId,
|
||||||
pub room: String,
|
pub room: RoomId,
|
||||||
pub msg: String,
|
pub msg: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(ActixMessage)]
|
||||||
|
#[rtype(result = "Uuid")]
|
||||||
|
pub struct CreateRoom {
|
||||||
|
pub session: SessionId,
|
||||||
|
}
|
||||||
#[derive(ActixMessage)]
|
#[derive(ActixMessage)]
|
||||||
#[rtype(result = "()")]
|
#[rtype(result = "()")]
|
||||||
pub struct JoinRoom {
|
pub struct JoinRoom {
|
||||||
pub session: SessionId,
|
pub session: SessionId,
|
||||||
pub room: String,
|
pub room: RoomId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(ActixMessage)]
|
#[derive(ActixMessage)]
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
pub mod ws_messages;
|
||||||
use actix::Addr;
|
use actix::Addr;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
|
|
||||||
0
src/models/ws_messages.rs
Normal file
0
src/models/ws_messages.rs
Normal file
Loading…
Add table
Add a link
Reference in a new issue