Updated protocol

This commit is contained in:
2025-09-13 11:45:44 +02:00
parent 0919ec30d3
commit 642fe6cfcb
7 changed files with 334 additions and 34 deletions
+3 -3
View File
@@ -7,7 +7,7 @@ use std::{
use anyhow::Error;
use tungstenite::{Message, Utf8Bytes, WebSocket, accept};
use crate::types::{FromClient, ToClient, WsMessage};
use crate::types::{ClientMessage, ServerMessage, WsMessage};
#[derive(Clone)]
pub struct Client(Arc<Mutex<WebSocket<TcpStream>>>);
@@ -37,7 +37,7 @@ impl Hash for Client {
}
impl Client {
pub fn read(&self) -> crate::Result<Option<WsMessage<FromClient>>> {
pub fn read(&self) -> crate::Result<Option<WsMessage<ClientMessage>>> {
match self.0.lock().unwrap().read()? {
Message::Text(t) => {
let v = t.to_string();
@@ -55,7 +55,7 @@ impl Client {
}
}
pub fn send(&self, m: ToClient) -> crate::Result<()> {
pub fn send(&self, m: ServerMessage) -> crate::Result<()> {
self.0
.lock()
.unwrap()
+30 -15
View File
@@ -20,7 +20,7 @@ pub use tungstenite;
use crate::{
client::Client,
plugin::DynPlugin,
types::{ToClient, data},
types::{ClientMessage, WsMessage},
};
pub use once_cell;
@@ -122,23 +122,38 @@ impl Server {
// The main req/res loop
loop {
match client.read()? {
Some(req) => {
println!("Request: {:?}", req);
for plugin in self.plugins.lock().unwrap().iter_mut() {
plugin.on_request(&req, self);
Some(WsMessage::FromClient(req)) => match req {
ClientMessage::SendMessage {
channel_id,
contents,
} => {
Self::LOGGER.info(format!("SendMessage to {channel_id}: {contents}"));
}
for c in self.clients.lock().unwrap().iter() {
if c == &client {
self.wrap_err(
&client,
c.send(ToClient::Message(data::Message {
from: format!("Server"),
contents: format!("Hello"),
})),
)?;
}
ClientMessage::EditMessage {
channel_id,
message_id,
new_contents,
} => {
Self::LOGGER.info(format!(
"EditMessage {message_id} in {channel_id}: {new_contents}"
));
}
ClientMessage::DeleteMessage {
channel_id,
message_id,
} => {
Self::LOGGER.info(format!("DeleteMessage {message_id} in {channel_id}"));
}
},
Some(WsMessage::Binary(b)) => {
Self::LOGGER.info(format!("Binary message: {b:?}"));
}
Some(WsMessage::String(s)) => {
Self::LOGGER.info(format!("String message: {s}"));
}
None => {
+2 -2
View File
@@ -2,7 +2,7 @@ use std::sync::Arc;
use crate::{
Server,
types::{FromClient, WsMessage},
types::{ClientMessage, WsMessage},
};
pub type DynPlugin = Box<dyn Plugin + Send + Sync>;
@@ -10,7 +10,7 @@ pub type DynPlugin = Box<dyn Plugin + Send + Sync>;
pub trait Plugin {
fn init(&mut self, server: &Arc<Server>);
#[allow(unused_variables)]
fn on_request(&mut self, msg: &WsMessage<FromClient>, server: &Arc<Server>) -> bool {
fn on_request(&mut self, msg: &WsMessage<ClientMessage>, server: &Arc<Server>) -> bool {
false
}
}
+63 -12
View File
@@ -1,27 +1,60 @@
use serde::{Deserialize, Serialize};
use tungstenite::Bytes;
/// Messages sent *from the client* (user’s app) to the server
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
pub enum FromClient {
SendMessage(String),
pub enum ClientMessage {
/// Send a message to a channel
SendMessage {
channel_id: String,
contents: String,
},
/// Edit a message (if allowed)
EditMessage {
channel_id: String,
message_id: String,
new_contents: String,
},
/// Delete a message (if allowed)
DeleteMessage {
channel_id: String,
message_id: String,
},
}
/// Messages sent *from the server* to the client
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
pub enum FromServer {}
pub enum ServerMessage {
/// Successful authentication
Authenticated { user_id: String },
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
pub enum ToClient {
Message(data::Message),
/// Error responses
Error { message: String },
/// A new message in a channel
MessageCreate(data::Message),
/// A message was edited
MessageUpdate(data::Message),
/// A message was deleted
MessageDelete {
channel_id: String,
message_id: String,
},
/// Presence updates
PresenceUpdate { user_id: String, status: String },
/// Typing indicator
Typing { user_id: String, channel_id: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
pub enum ToServer {}
/// WebSocket for client messages
/// WebSocket wrapper
#[derive(Debug, Clone)]
pub enum WsMessage<T: Serialize + for<'de> Deserialize<'de>> {
FromClient(T),
@@ -29,12 +62,30 @@ pub enum WsMessage<T: Serialize + for<'de> Deserialize<'de>> {
String(String),
}
/// Shared data structures
pub mod data {
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Message {
pub id: String,
pub channel_id: u8,
pub from: String,
pub contents: String,
pub timestamp: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Channel {
pub id: usize,
pub name: String,
pub kind: ChannelKind,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ChannelKind {
Text,
Voice,
}
}