made server configurable

This commit is contained in:
michael-bailey 2022-06-21 23:54:59 +02:00
parent 47092844c4
commit 715f6c1c4c
9 changed files with 161 additions and 50 deletions

View File

@ -33,6 +33,7 @@ async-trait = "0.1.52"
actix = "0.13"
mlua = { version = "0.7.3", features=["lua54", "async", "serde", "macros"] }
libloading = "0.7"
toml = "0.4.2"
aquamarine = "0.1.11"
tokio-stream = "0.1.9"

View File

@ -38,7 +38,7 @@ use crate::{
Client,
},
network::NetworkOutput,
prelude::ObservableMessage,
prelude::messages::ObservableMessage,
};
#[derive(Message)]
@ -165,7 +165,7 @@ impl ClientManager {
addr: Addr<Client>,
) {
println!("[ClientManager] adding client");
use crate::prelude::ObservableMessage::Subscribe;
use crate::prelude::messages::ObservableMessage::Subscribe;
let recp = ctx.address().recipient::<ClientObservableMessage>();
addr.do_send(Subscribe(recp));
self.clients.insert(uuid, addr);
@ -173,7 +173,7 @@ impl ClientManager {
fn remove_client(&mut self, ctx: &mut Context<ClientManager>, uuid: Uuid) {
println!("[ClientManager] removing client");
use crate::prelude::ObservableMessage::Unsubscribe;
use crate::prelude::messages::ObservableMessage::Unsubscribe;
let recp = ctx.address().recipient::<ClientObservableMessage>();
if let Some(addr) = self.clients.remove(&uuid) {
addr.do_send(Unsubscribe(recp));

View File

@ -8,12 +8,64 @@ pub(crate) mod client_management;
pub(crate) mod network;
pub(crate) mod prelude;
use std::env::args;
use server::Server;
use tokio::time::{sleep, Duration};
use clap::{App, Arg, value_parser};
use openssl::version::version;
#[actix::main()]
async fn main() {
let _server = Server::new();
let args = App::new("Rust Chat Server")
.author("Michael Bailey & Mitchel Hardie")
.version("0.1.0")
.about("A chat server written in rust, with a custom json protocol, based on serde and actix")
.arg(
Arg::new("port")
.short('p')
.long("port")
.takes_value(true)
.value_parser(value_parser!(usize))
.default_value("5600")
.help("overrides the default port")
)
.arg(
Arg::new("server name")
.short('n')
.long("name")
.takes_value(true)
.help("overrides the default port of the server")
)
.arg(
Arg::new("server owner")
.short('o')
.long("owner")
.takes_value(true)
.help("overrides the owner of the server")
)
.after_help("This is a chat server made to test out writing a full application in rust \
It has evolved over time to use different frameworks\
It is currently using actix")
.get_matches();
let mut server_builder = Server::create();
if let Some(port) = args.get_one::<usize>("port") {
server_builder = server_builder.port(*port);
println!("got port number {:?}", port);
}
if let Some(name) = args.get_one::<String>("server name") {
server_builder = server_builder.name(name.clone());
println!("got server name number {:?}", name)
}
if let Some(owner) = args.get_one::<String>("server owner") {
server_builder = server_builder.owner(owner.clone());
println!("got server owner number {:?}", owner)
}
let _server = server_builder.build();
loop {
sleep(Duration::from_millis(1000)).await;
}

View File

@ -27,7 +27,7 @@ use tokio::{
sync::Mutex,
};
use crate::prelude::ObservableMessage;
use crate::prelude::messages::ObservableMessage;
/// This is a message that can be sent to the Connection.
#[derive(Message)]

View File

@ -22,7 +22,7 @@ use serde_json::{from_str, to_string};
use crate::{
network::{connection::ConnectionOuput, Connection, ConnectionMessage},
prelude::ObservableMessage,
prelude::messages::ObservableMessage,
};
#[derive(Debug, Clone, Copy)]

View File

@ -0,0 +1,37 @@
use actix::{Actor, Addr};
use super::*;
pub struct ServerBuilder {
pub(super) name: Option<String>,
pub(super) port: Option<usize>,
pub(super) owner: Option<String>,
}
impl ServerBuilder {
pub(super) fn new() -> Self {
Self {
name: None,
port: None,
owner: None,
}
}
pub fn port(mut self, port: usize) -> Self {
self.port = Some(port);
self
}
pub fn name(mut self, name: String) -> Self {
self.name = Some(name);
self
}
pub fn owner(mut self, owner: String) -> Self {
self.owner = Some(owner);
self
}
pub fn build(self) -> Addr<Server> {
Server::from(self).start()
}
}

View File

@ -0,0 +1,16 @@
/// Configuration for the server
pub(super) struct ServerConfig {
pub(super) port: usize,
pub(super) name: String,
pub(super) owner: String,
}
impl Default for ServerConfig {
fn default() -> Self {
ServerConfig {
owner: "john_smith@example.com".to_string(),
name: "default server name".to_string(),
port: 5600,
}
}
}

12
server/src/server/mod.rs Normal file
View File

@ -0,0 +1,12 @@
//! # actix_server
//! this holds the server actor
//! the server acts as teh main actor
//! and supervisor to the actor system.
mod server;
mod config;
mod builder;
use config::ServerConfig;
pub use server::Server;
pub(crate) use builder::ServerBuilder;

View File

@ -1,39 +1,19 @@
//! # actix_server
//! this holds the server actor
//! the server acts as teh main actor
//! and supervisor to the actor system.
use actix::{
fut::wrap_future,
Actor,
ActorFutureExt,
Addr,
AsyncContext,
Context,
Handler,
};
use foundation::{messages::network::NetworkSockOut, ClientDetails};
use crate::{
client_management::{
Client,
ClientManager,
ClientManagerMessage,
ClientManagerOutput,
},
network::{
Connection,
ConnectionInitiator,
ConnectionMessage,
NetworkManager,
NetworkMessage,
NetworkOutput,
},
};
use actix::{Actor, ActorFutureExt, Addr, AsyncContext, Context, ContextFutureSpawner, Handler};
use actix::fut::wrap_future;
use foundation::ClientDetails;
use foundation::messages::network::NetworkSockOut::GotInfo;
use crate::client_management::{Client, ClientManager, ClientManagerOutput};
use crate::client_management::ClientManagerMessage::AddClient;
use crate::network::{Connection, NetworkManager, NetworkMessage, NetworkOutput};
use crate::network::ConnectionMessage::{CloseConnection, SendData};
use crate::network::NetworkOutput::{InfoRequested, NewClient};
use crate::server::{builder, ServerBuilder};
use crate::server::config::ServerConfig;
/// This struct is the main actor of the server.
/// all other actors are ran through here.
pub struct Server {
config: ServerConfig,
network_manager: Option<Addr<NetworkManager>>,
client_management: Option<Addr<ClientManager>>,
}
@ -41,10 +21,15 @@ pub struct Server {
impl Server {
pub(crate) fn new() -> Addr<Self> {
Server {
config: Default::default(),
network_manager: None,
client_management: None,
}
.start()
.start()
}
pub fn create() -> builder::ServerBuilder {
ServerBuilder::new()
}
pub(crate) fn client_request(
@ -53,7 +38,6 @@ impl Server {
addr: Addr<Connection>,
details: ClientDetails,
) {
use ClientManagerMessage::AddClient;
if let Some(mgr) = self.client_management.as_ref() {
let client = Client::new(addr, details.clone());
mgr.do_send(AddClient(details.uuid, client));
@ -65,21 +49,19 @@ impl Server {
ctx: &mut <Self as Actor>::Context,
sender: Addr<Connection>,
) {
use ConnectionMessage::{CloseConnection, SendData};
use NetworkSockOut::GotInfo;
let fut = wrap_future(
sender.send(SendData(
serde_json::to_string(&GotInfo {
server_name: "String".to_owned(),
server_owner: "String".to_owned(),
})
.expect("Failed to serialise"),
.expect("Failed to serialise"),
)),
)
// equivalent to using .then() in js
.map(move |_out, _act: &mut Self, _ctx| {
sender.do_send(CloseConnection);
});
// equivalent to using .then() in js
.map(move |_out, _act: &mut Self, _ctx| {
sender.do_send(CloseConnection);
});
ctx.spawn(fut);
}
}
@ -110,9 +92,6 @@ impl Handler<NetworkOutput> for Server {
msg: NetworkOutput,
ctx: &mut Self::Context,
) -> Self::Result {
use ConnectionMessage::{CloseConnection, SendData};
use NetworkOutput::{InfoRequested, NewClient};
use NetworkSockOut::GotInfo;
println!("[ServerActor] received message");
match msg {
// This uses promise like funcionality to queue
@ -136,3 +115,17 @@ impl Handler<ClientManagerOutput> for Server {
todo!()
}
}
impl From<builder::ServerBuilder> for Server {
fn from(builder: ServerBuilder) -> Self {
Server {
config: ServerConfig {
port: builder.port.unwrap_or(5600),
name: builder.name.unwrap_or_else(|| "Default Name".to_string()),
owner: builder.owner.unwrap_or_else(|| "Default owner".to_string()),
},
network_manager: None,
client_management: None
}
}
}