Handshake
This commit is contained in:
+35
@@ -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());
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user