Updated protocol
This commit is contained in:
@@ -5,6 +5,7 @@ edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.99"
|
||||
chrono = "0.4.42"
|
||||
libloading = { version = "0.8.8", optional = true }
|
||||
once_cell = "1.21.3"
|
||||
serde = { version = "1.0.219", features = ["serde_derive"] }
|
||||
|
||||
Generated
+231
-1
@@ -2,12 +2,27 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
@@ -17,18 +32,47 @@ dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "65193589c6404eb80b450d618eaf9a2cafaaafd57ecce47370519ef674a7bd44"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
|
||||
dependencies = [
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cli"
|
||||
version = "0.1.0"
|
||||
@@ -36,6 +80,12 @@ dependencies = [
|
||||
"voxa-server",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
@@ -71,6 +121,12 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d"
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
@@ -116,12 +172,46 @@ version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.64"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone-haiku"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.175"
|
||||
@@ -150,6 +240,15 @@ version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
@@ -218,6 +317,12 @@ dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.20"
|
||||
@@ -267,6 +372,12 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.106"
|
||||
@@ -344,6 +455,7 @@ name = "voxa-server"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"libloading",
|
||||
"once_cell",
|
||||
"serde",
|
||||
@@ -360,19 +472,137 @@ dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
"rustversion",
|
||||
"wasm-bindgen-macro",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.62.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link 0.2.0",
|
||||
"windows-result",
|
||||
"windows-strings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-implement"
|
||||
version = "0.60.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-interface"
|
||||
version = "0.59.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||
|
||||
[[package]]
|
||||
name = "windows-result"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-strings"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows-link 0.1.3",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
|
||||
@@ -2,7 +2,10 @@ setInterval(() => {
|
||||
const ws = new WebSocket('ws://localhost:7080');
|
||||
|
||||
function sendMessage(message) {
|
||||
ws.send(JSON.stringify({ type: 'send_message', params: message }));
|
||||
ws.send(JSON.stringify({ type: 'send_message', params: {
|
||||
channel_id: 'Hello',
|
||||
contents: message
|
||||
}}));
|
||||
}
|
||||
|
||||
ws.onopen = () => {
|
||||
|
||||
+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()
|
||||
|
||||
+29
-14
@@ -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