Updated protocol
This commit is contained in:
+3
-3
@@ -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
@@ -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
@@ -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
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user