Handshake

This commit is contained in:
2025-09-15 18:23:27 +02:00
parent 0f3e0ac68a
commit 2b7abc505b
5 changed files with 78 additions and 15 deletions
+35
View File
@@ -17,6 +17,8 @@ pub use once_cell;
#[derive(serde::Serialize, serde::Deserialize)]
pub struct ServerConfig {
server_name: String,
server_id: String,
port: u16,
channels: Vec<types::data::Channel>,
}
@@ -34,6 +36,8 @@ impl Default for ServerConfig {
fn default() -> Self {
Self {
port: 7080,
server_name: format!("Server Name"),
server_id: format!("offline-server"),
channels: Vec::new(),
}
}
@@ -108,6 +112,37 @@ impl Server {
// Initialize client
let client = Client::new(stream)?;
// Initialize handshake
self.wrap_err(
&client,
client.send(types::handshake::ServerDetails {
name: self.config.server_name.clone(),
id: self.config.server_id.clone(),
version: format!("0.0.1"),
}),
)?;
match self.wrap_err(&client, client.read_t::<types::handshake::ClientDetails>())? {
Some(types::WsMessage::Message(_)) => {
// Do auth stuff
self.wrap_err(
&client,
client.send(types::ServerMessage::Authenticated {
user_id: format!("<placeholder>"),
}),
)?;
}
Some(_) => {
self.wrap_err(
&client,
client.send(types::ResponseError::InvalidHandshake(format!(
"Invalid handshake"
))),
)?;
}
None => {}
}
// Insert to the set of all connected clients
self.clients.lock().unwrap().insert(client.clone());
+1 -1
View File
@@ -15,7 +15,7 @@ pub fn send(
if contents.is_empty() {
server.wrap_err(
&client,
client.send(types::data::ResponseError::InvalidRequest(format!(
client.send(types::ResponseError::InvalidRequest(format!(
"Invalid message: empty message"
))),
)?;
+26 -12
View File
@@ -17,9 +17,7 @@ pub enum ClientMessage {
},
/// Delete a message (if allowed)
DeleteMessage {
message_id: usize,
},
DeleteMessage { message_id: usize },
}
/// Messages sent *from the server* to the client
@@ -27,9 +25,7 @@ pub enum ClientMessage {
#[serde(tag = "type", content = "params", rename_all = "snake_case")]
pub enum ServerMessage {
/// Successful authentication
Authenticated {
user_id: String,
},
Authenticated { user_id: String },
TempMessage {
message: String,
@@ -60,6 +56,16 @@ pub enum ServerMessage {
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "error", content = "message", rename_all = "snake_case")]
pub enum ResponseError {
InvalidRequest(String),
InvalidHandshake(String),
Unauthorized(String),
NotFound(String),
InternalError(String),
}
/// WebSocket wrapper
#[derive(Debug, Clone)]
pub enum WsMessage<T: Serialize + for<'de> Deserialize<'de>> {
@@ -94,13 +100,21 @@ pub mod data {
Text,
Voice,
}
}
pub mod handshake {
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "error", content = "message", rename_all = "snake_case")]
pub enum ResponseError {
InvalidRequest(String),
Unauthorized(String),
NotFound(String),
InternalError(String),
pub struct ServerDetails {
pub version: String,
pub name: String,
pub id: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientDetails {
pub version: String,
pub auth_token: String,
}
}
+14 -2
View File
@@ -6,7 +6,7 @@ use std::{
};
use anyhow::anyhow;
use serde::Serialize;
use serde::{Deserialize, Serialize};
use crate::types::{ClientMessage, WsMessage};
@@ -196,7 +196,9 @@ impl Client {
/// - Ok(Some(WsMessage)) on an application message (text/binary)
/// - Ok(None) if the connection should be closed (close received / read EOF)
/// - Err on protocol or IO errors.
pub fn read(&self) -> crate::Result<Option<WsMessage<ClientMessage>>> {
pub fn read_t<T: Serialize + for<'de> Deserialize<'de>>(
&self,
) -> crate::Result<Option<WsMessage<T>>> {
let mut stream = self.0.try_clone()?;
let mut message_payload = Vec::new();
@@ -311,6 +313,16 @@ impl Client {
Ok(Some(message))
}
/// Read a full WebSocket message, handling fragmentation and control frames.
///
/// Returns:
/// - Ok(Some(WsMessage)) on an application message (text/binary)
/// - Ok(None) if the connection should be closed (close received / read EOF)
/// - Err on protocol or IO errors.
pub fn read(&self) -> crate::Result<Option<WsMessage<ClientMessage>>> {
self.read_t()
}
}
impl Clone for Client {