2022-08-12 20:32:22 +00:00
|
|
|
use std::{
|
|
|
|
collections::HashMap,
|
|
|
|
fmt,
|
|
|
|
io::{Read, Write},
|
|
|
|
net::{Shutdown, SocketAddr, TcpStream},
|
|
|
|
sync::{Arc, Mutex},
|
2022-07-29 19:55:21 +00:00
|
|
|
};
|
2022-07-01 19:32:20 +00:00
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
use tungstenite::{accept, Message, WebSocket};
|
|
|
|
|
|
|
|
use super::server::PLUGINS_MANAGER;
|
|
|
|
use crate::plugins::manager::PluginsManagerType;
|
|
|
|
|
|
|
|
/// Max length of a TCP and UDP packet
|
2022-06-17 11:43:23 +00:00
|
|
|
pub const MAX_PACKET_LEN: usize = 65536;
|
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
#[derive(Debug, Clone)]
|
2022-06-04 11:58:21 +00:00
|
|
|
pub struct Client {
|
2022-08-12 20:52:47 +00:00
|
|
|
pub id: usize,
|
2022-08-12 20:32:22 +00:00
|
|
|
pub stream: ClientStream,
|
|
|
|
pub map: HashMap<String, ClientMapValue>,
|
|
|
|
pub plugins_manager: PluginsManagerType,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum ClientMapValue {
|
|
|
|
/// String type
|
|
|
|
String(String),
|
|
|
|
/// Vector with String type
|
|
|
|
Array(Vec<String>),
|
|
|
|
/// bool type
|
|
|
|
Bool(bool),
|
|
|
|
/// isize type
|
|
|
|
Int(isize),
|
|
|
|
/// usize type
|
|
|
|
UInt(usize),
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Connection stream of the client
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub enum ClientStream {
|
|
|
|
/// TCP stream
|
|
|
|
TCP(Arc<TcpStream>),
|
|
|
|
/// WebSocket stream
|
|
|
|
WebSocket(Arc<Mutex<WebSocket<TcpStream>>>),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<TcpStream> for Client {
|
|
|
|
fn from(stream: TcpStream) -> Self {
|
|
|
|
Self {
|
2022-08-12 20:52:47 +00:00
|
|
|
id: 0,
|
2022-08-12 20:32:22 +00:00
|
|
|
stream: ClientStream::TCP(Arc::new(stream)),
|
|
|
|
map: HashMap::new(),
|
|
|
|
plugins_manager: PLUGINS_MANAGER.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<WebSocket<TcpStream>> for Client {
|
|
|
|
fn from(stream: WebSocket<TcpStream>) -> Self {
|
|
|
|
Self {
|
2022-08-12 20:52:47 +00:00
|
|
|
id: 0,
|
2022-08-12 20:32:22 +00:00
|
|
|
stream: ClientStream::WebSocket(Arc::new(Mutex::new(stream))),
|
|
|
|
map: HashMap::new(),
|
|
|
|
plugins_manager: PLUGINS_MANAGER.clone(),
|
|
|
|
}
|
|
|
|
}
|
2022-06-04 11:58:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Client {
|
2022-08-12 20:32:22 +00:00
|
|
|
/// Create a new TCP Client instance
|
2022-08-12 20:52:47 +00:00
|
|
|
pub fn new_tcp(stream: TcpStream, id: usize) -> Self {
|
|
|
|
let mut client = Self::from(stream);
|
|
|
|
|
|
|
|
client.id = id;
|
|
|
|
|
|
|
|
client
|
2022-06-04 11:58:21 +00:00
|
|
|
}
|
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
/// Create a new WebSocket Client instance
|
2022-08-12 20:52:47 +00:00
|
|
|
pub fn new_websocket(stream: TcpStream, id: usize) -> anyhow::Result<Self> {
|
2022-08-12 20:32:22 +00:00
|
|
|
let websocket = accept(stream)?;
|
2022-06-04 11:58:21 +00:00
|
|
|
|
2022-08-12 20:52:47 +00:00
|
|
|
let mut client = Self::from(websocket);
|
|
|
|
|
|
|
|
client.id = id;
|
|
|
|
|
|
|
|
Ok(client)
|
2022-08-12 20:32:22 +00:00
|
|
|
}
|
2022-06-04 11:58:21 +00:00
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
/// Recieve a message from the client
|
|
|
|
pub fn read(&self) -> anyhow::Result<String> {
|
|
|
|
// read the message from the stream
|
|
|
|
let mut msg = match &self.stream {
|
|
|
|
ClientStream::TCP(stream) => {
|
|
|
|
// allocate an empty buffer
|
|
|
|
let mut buf = [0; MAX_PACKET_LEN];
|
2022-06-25 19:38:08 +00:00
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
// read the message and get length of it
|
|
|
|
let len = stream.as_ref().read(&mut buf)?;
|
|
|
|
|
|
|
|
// select only used bytes in the buffer
|
|
|
|
let buf = &buf[0..len];
|
|
|
|
|
|
|
|
// decode buffer (&[u8]) to a String
|
|
|
|
String::from_utf8(buf.to_vec())?
|
|
|
|
}
|
|
|
|
ClientStream::WebSocket(stream) => {
|
|
|
|
// read the message from the stream
|
|
|
|
let msg = stream.lock().unwrap().read_message()?;
|
|
|
|
|
|
|
|
// decode message to a String
|
|
|
|
msg.to_string()
|
|
|
|
}
|
|
|
|
};
|
2022-08-04 14:35:33 +00:00
|
|
|
|
|
|
|
// remove new line characters
|
2022-08-12 20:32:22 +00:00
|
|
|
while msg.ends_with('\n') || msg.ends_with('\r') {
|
|
|
|
msg.pop();
|
2022-08-04 14:35:33 +00:00
|
|
|
}
|
2022-06-04 11:58:21 +00:00
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
Ok(msg)
|
2022-06-04 11:58:21 +00:00
|
|
|
}
|
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
/// Send a message to the client
|
|
|
|
pub fn send<S>(&self, msg: S) -> anyhow::Result<()>
|
2022-07-29 19:55:21 +00:00
|
|
|
where
|
2022-08-12 20:32:22 +00:00
|
|
|
S: ToString,
|
|
|
|
S: fmt::Display,
|
2022-07-29 19:55:21 +00:00
|
|
|
{
|
2022-08-12 20:32:22 +00:00
|
|
|
// convert the message into a string
|
|
|
|
let msg = msg.to_string();
|
|
|
|
|
|
|
|
// convert the message into bytes to send it
|
|
|
|
let buf = msg.as_bytes();
|
2022-06-04 18:10:21 +00:00
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
// send the message
|
|
|
|
match &self.stream {
|
|
|
|
ClientStream::TCP(stream) => stream.as_ref().write_all(buf)?,
|
|
|
|
ClientStream::WebSocket(stream) => {
|
|
|
|
stream.lock().unwrap().write_message(Message::from(msg))?
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
2022-06-04 11:58:21 +00:00
|
|
|
}
|
2022-07-29 20:10:49 +00:00
|
|
|
|
2022-08-12 20:32:22 +00:00
|
|
|
/// Returns the socket address of the remote peer of this connection.
|
|
|
|
pub fn peer_addr(&self) -> anyhow::Result<SocketAddr> {
|
|
|
|
let addr = match &self.stream {
|
|
|
|
ClientStream::TCP(stream) => stream.peer_addr(),
|
|
|
|
ClientStream::WebSocket(stream) => stream.lock().unwrap().get_ref().peer_addr(),
|
|
|
|
}?;
|
|
|
|
|
|
|
|
Ok(addr)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Flush this output stream, ensuring that all intermediately buffered contents reach their destination.
|
|
|
|
pub fn flush(&self) -> anyhow::Result<()> {
|
|
|
|
match &self.stream {
|
|
|
|
ClientStream::TCP(stream) => stream.as_ref().flush()?,
|
|
|
|
ClientStream::WebSocket(_stream) => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Close the connection
|
|
|
|
pub fn close(&self) -> anyhow::Result<()> {
|
|
|
|
match &self.stream {
|
|
|
|
ClientStream::TCP(stream) => stream.shutdown(Shutdown::Both)?,
|
|
|
|
ClientStream::WebSocket(stream) => stream.lock().unwrap().close(None)?,
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
2022-07-29 20:10:49 +00:00
|
|
|
}
|
2022-06-04 11:58:21 +00:00
|
|
|
}
|