increment version
+ clap crate ~ attempting fix on getting info + added clap arg parsing + added rudementary client, remove and update and error
This commit is contained in:
parent
164542a56b
commit
a1474d01de
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "rust-chat-server"
|
||||
version = "0.1.0"
|
||||
version = "0.1.5"
|
||||
authors = ["Mitchell <mitchellhardie1@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
|
|
@ -22,6 +22,7 @@ zeroize = "1.1.0"
|
|||
cursive = { version = "0.15.0", default-features = false, features = ["crossterm-backend"]}
|
||||
crossterm = "0.17.7"
|
||||
log = "0.4"
|
||||
clap = "3.0.0-beta.1"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
use std::{
|
||||
net::TcpStream,
|
||||
io::{Write, Read}
|
||||
};
|
||||
use std::{net::TcpStream, io::{Write, Read}, io};
|
||||
use crate::{
|
||||
server::client::client_profile::Client,
|
||||
commands::Commands,
|
||||
};
|
||||
use zeroize::Zeroize;
|
||||
use std::time::Duration;
|
||||
use async_std::net::SocketAddrV4;
|
||||
use std::str::FromStr;
|
||||
use std::net::SocketAddr;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
|
||||
pub struct ClientApi {
|
||||
|
|
@ -37,29 +33,31 @@ impl ClientApi {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_on_client_add(&mut self, Fn: fn(Client) -> ()) {
|
||||
self.on_client_add_handle = Fn;
|
||||
pub fn set_on_client_add(&mut self, func: fn(Client) -> ()) {
|
||||
self.on_client_add_handle = func;
|
||||
}
|
||||
|
||||
pub fn set_on_client_removed(&mut self, Fn: fn(String) -> ()) {
|
||||
self.on_client_remove_handle = Fn;
|
||||
pub fn set_on_client_removed(&mut self, func: fn(String) -> ()) {
|
||||
self.on_client_remove_handle = func;
|
||||
}
|
||||
|
||||
pub fn get_info(host: &str) -> Option<Commands> {
|
||||
pub fn get_info(host: &str) -> Result<Commands, io::Error> {
|
||||
let mut buffer: [u8; 1024] = [0; 1024];
|
||||
let addr = SocketAddr::from_str(host).ok()?;
|
||||
let mut stream = TcpStream::connect_timeout(&addr, Duration::from_millis(500)).ok()?;
|
||||
let addr = host.parse().unwrap();
|
||||
let mut stream = TcpStream::connect_timeout(&addr, Duration::from_millis(10000))?;
|
||||
|
||||
stream.read(&mut buffer).ok()?;
|
||||
stream.read(&mut buffer)?;
|
||||
|
||||
match Commands::from(&buffer) {
|
||||
Commands::Request(None) => {
|
||||
buffer.zeroize();
|
||||
stream.write_all(Commands::Info(None).to_string().as_bytes()).unwrap();
|
||||
stream.read(&mut buffer).ok()?;
|
||||
Some(Commands::from(String::from(String::from_utf8_lossy(&buffer))))
|
||||
let a = stream.read(&mut buffer);
|
||||
a?;
|
||||
Ok(Commands::from(String::from(String::from_utf8_lossy(&buffer))))
|
||||
},
|
||||
_ => {
|
||||
None
|
||||
Err(io::Error::new(io::ErrorKind::InvalidData, "the data was not expected"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
120
src/main.rs
120
src/main.rs
|
|
@ -1,69 +1,86 @@
|
|||
#![feature(test)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
mod client_api;
|
||||
mod commands;
|
||||
mod server;
|
||||
|
||||
|
||||
use crate::server::server_profile::Server;
|
||||
use client_api::ClientApi;
|
||||
use crossterm::ErrorKind;
|
||||
use cursive::{
|
||||
Cursive,
|
||||
menu::*,
|
||||
event::Key,
|
||||
views::{ Dialog, TextView, LinearLayout, ListView, ResizedView, Panel },
|
||||
Rect,
|
||||
CursiveExt,
|
||||
align::{Align, HAlign},
|
||||
align::Align,
|
||||
view::SizeConstraint,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use crossterm::ErrorKind;
|
||||
use log::info;
|
||||
use clap::{App, Arg};
|
||||
|
||||
use crate::server::server_profile::Server;
|
||||
|
||||
fn main() -> Result<(), ErrorKind> {
|
||||
let server = Server::new("Server-01", "0.0.0.0:6000", "noreply@email.com");
|
||||
let server_arc = Arc::new(server);
|
||||
let s1 = server_arc.clone();
|
||||
let s2 = s1.clone();
|
||||
|
||||
cursive::logger::init();
|
||||
let args = App::new("--rust chat server--")
|
||||
.version("0.1.5")
|
||||
.author("Mitchel Hardie <mitch161>, Michael Bailey <michael-bailey>")
|
||||
.about("this is a chat server developed in rust, depending on the version one of two implementations will be used")
|
||||
.arg(Arg::with_name("graphical")
|
||||
.short('g')
|
||||
.takes_value(false)
|
||||
.about("Enables graphical mode"))
|
||||
.get_matches();
|
||||
|
||||
info!("Main: init Display");
|
||||
let mut Display = Cursive::default();
|
||||
if args.is_present("graphical") {
|
||||
let server = Server::new("Server-01", "0.0.0.0:6000", "noreply@email.com");
|
||||
let server_arc = Arc::new(server);
|
||||
let s1 = server_arc.clone();
|
||||
let s2 = s1.clone();
|
||||
|
||||
info!("Main: setting up callbacks");
|
||||
Display.add_global_callback(Key::Backspace, |s| s.quit());
|
||||
Display.add_global_callback(Key::Tab, |s| s.toggle_debug_console());
|
||||
Display.add_global_callback(Key::Esc, |s| s.select_menubar());
|
||||
cursive::logger::init();
|
||||
|
||||
info!("Main: setting up menu bar");
|
||||
let _ = Display.menubar()
|
||||
.add_subtree("Server",
|
||||
MenuTree::new()
|
||||
.leaf("About",
|
||||
|s| s.add_layer(About()))
|
||||
.delimiter()
|
||||
.leaf("quit", |s| s.quit()))
|
||||
.add_subtree("File",
|
||||
MenuTree::new()
|
||||
.leaf("Start", move |s| {s1.start();})
|
||||
.leaf("Stop", move |s| {s2.stop();})
|
||||
.delimiter()
|
||||
.leaf("Debug", |s| {s.toggle_debug_console();}));
|
||||
info!("Main: entering loop");
|
||||
Display.add_layer(Control_Panel());
|
||||
Display.run();
|
||||
Ok(())
|
||||
info!("Main: init display");
|
||||
let mut display = Cursive::default();
|
||||
|
||||
info!("Main: setting up callbacks");
|
||||
display.add_global_callback(Key::Backspace, |s| s.quit());
|
||||
display.add_global_callback(Key::Tab, |s| s.toggle_debug_console());
|
||||
display.add_global_callback(Key::Esc, |s| s.select_menubar());
|
||||
|
||||
info!("Main: setting up menu bar");
|
||||
let _ = display.menubar()
|
||||
.add_subtree("Server",
|
||||
MenuTree::new()
|
||||
.leaf("about",
|
||||
|s| s.add_layer(about()))
|
||||
.delimiter()
|
||||
.leaf("quit", |s| s.quit()))
|
||||
.add_subtree("File",
|
||||
MenuTree::new()
|
||||
.leaf("Start", move |_s| {let _ = s1.start();})
|
||||
.leaf("Stop", move |_s| {let _ = s2.stop();})
|
||||
.delimiter()
|
||||
.leaf("Debug", |s| {s.toggle_debug_console();}));
|
||||
info!("Main: entering loop");
|
||||
display.add_layer(control_panel());
|
||||
display.run();
|
||||
Ok(())
|
||||
} else {
|
||||
let server = Server::new("Server-01", "0.0.0.0:6000", "noreply@email.com");
|
||||
server.start()?;
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
fn About() -> Dialog {
|
||||
fn about() -> Dialog {
|
||||
Dialog::new()
|
||||
.content(TextView::new("Rust-Chat-Server\nmade by\n Mitchell Hardie\nMichael Bailey\nMit Licence")
|
||||
).button("Close", |s| {let _ = s.pop_layer(); s.add_layer(Control_Panel())} )
|
||||
).button("Close", |s| {let _ = s.pop_layer(); s.add_layer(control_panel())} )
|
||||
}
|
||||
|
||||
fn Launch_screen() -> Dialog {
|
||||
fn launch_screen() -> Dialog {
|
||||
Dialog::new()
|
||||
.content(TextView::new("\
|
||||
Server.
|
||||
|
|
@ -74,7 +91,7 @@ fn Launch_screen() -> Dialog {
|
|||
.button("ok", |s| {s.pop_layer();})
|
||||
}
|
||||
|
||||
fn Control_Panel() -> ResizedView<Panel<LinearLayout>> {
|
||||
fn control_panel() -> ResizedView<Panel<LinearLayout>> {
|
||||
|
||||
let mut root = LinearLayout::horizontal();
|
||||
let mut left = LinearLayout::vertical();
|
||||
|
|
@ -101,6 +118,7 @@ mod tests {
|
|||
use std::thread::spawn;
|
||||
use std::collections::HashMap;
|
||||
use crate::commands::Commands;
|
||||
use log::info;
|
||||
|
||||
#[test]
|
||||
fn test_server_info() {
|
||||
|
|
@ -113,7 +131,8 @@ mod tests {
|
|||
let _ = server.start().unwrap();
|
||||
|
||||
let api = ClientApi::get_info("127.0.0.1:6000");
|
||||
if api.is_some() {
|
||||
assert_eq!(api.is_ok(), true);
|
||||
if api.is_ok() {
|
||||
|
||||
let mut map = HashMap::new();
|
||||
map.insert("name".to_string(), name.to_string());
|
||||
|
|
@ -121,11 +140,30 @@ mod tests {
|
|||
|
||||
let expected = Commands::Info(Some(map));
|
||||
|
||||
|
||||
let api = api.unwrap();
|
||||
assert_eq!(api, expected);
|
||||
} else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_server_connect() {
|
||||
let name = "Server-01";
|
||||
let address = "0.0.0.0:6000";
|
||||
let owner = "noreply@email.com";
|
||||
|
||||
let server = Server::new(name, address, owner);
|
||||
let _ = server.start().unwrap();
|
||||
|
||||
let api = ClientApi::get_info("127.0.0.1:6000");
|
||||
assert_eq!(api.is_ok(), true);
|
||||
if let Commands::Success(Some(params)) = api.unwrap() {
|
||||
let mut api = ClientApi::new(address);
|
||||
|
||||
api.on_client_add_handle = |s| info!("new clinet: {:?}", s);
|
||||
api.on_client_remove_handle = |s| info!("removed clinet: {:?}", s);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +1,21 @@
|
|||
extern crate regex;
|
||||
|
||||
use std::{
|
||||
sync::Arc,
|
||||
net::{Shutdown, TcpStream},
|
||||
io::prelude::*,
|
||||
sync::Arc,
|
||||
io,
|
||||
sync::Mutex,
|
||||
time::{Instant, Duration},
|
||||
net::{TcpStream, Shutdown}
|
||||
};
|
||||
use crossbeam::{Sender, Receiver, TryRecvError, unbounded};
|
||||
|
||||
use crate::{
|
||||
server::{
|
||||
server_profile::ServerMessages,
|
||||
},
|
||||
commands::Commands
|
||||
|
||||
use crossbeam::{
|
||||
Sender,
|
||||
Receiver,
|
||||
TryRecvError,
|
||||
unbounded
|
||||
};
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
use log::info;
|
||||
|
||||
use crate::server::server_profile::ServerMessages;
|
||||
use crate::commands::Commands;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Client {
|
||||
|
|
@ -24,9 +24,9 @@ pub struct Client {
|
|||
pub username: String,
|
||||
pub address: String,
|
||||
|
||||
stream_arc: Arc<Mutex<TcpStream>>,
|
||||
last_heartbeat: Arc<Mutex<Instant>>,
|
||||
|
||||
heartbeat_ticker: Arc<Mutex<u8>>,
|
||||
stream_arc: Arc<Mutex<TcpStream>>,
|
||||
|
||||
pub sender: Sender<Commands>,
|
||||
receiver: Receiver<Commands>,
|
||||
|
|
@ -45,41 +45,57 @@ impl Client {
|
|||
username: username.to_string(),
|
||||
address: address.to_string(),
|
||||
|
||||
heartbeat_ticker: Arc::new(Mutex::new(5)),
|
||||
|
||||
sender,
|
||||
receiver,
|
||||
|
||||
server_sender,
|
||||
|
||||
last_heartbeat: Arc::new(Mutex::new(Instant::now())),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
// TODO: - add heartbeat timer.
|
||||
pub fn handle_connection(&self) {
|
||||
info!("{}: handling connection", self.uuid);
|
||||
|
||||
println!("buffer");
|
||||
let mut buffer = [0; 1024];
|
||||
|
||||
// test to see if there is anything for the client to receive from its channel
|
||||
println!("{}: channel checks", self.uuid);
|
||||
|
||||
match self.receiver.try_recv() {
|
||||
/*command is on the channel*/
|
||||
|
||||
Ok(Commands::Info(Some(params))) => {
|
||||
self.transmit_data(Commands::Info(Some(params)).to_string().as_str());
|
||||
Ok(Commands::ClientRemove(Some(params))) => {
|
||||
let retry: u8 = 3;
|
||||
'retry_loop1: loop {
|
||||
if retry < 1 {
|
||||
self.transmit_data(Commands::Error(None).to_string().as_str());
|
||||
break 'retry_loop1
|
||||
}
|
||||
self.transmit_data(Commands::ClientRemove(Some(params.clone())).to_string().as_str());
|
||||
let _ = self.stream_arc.lock().unwrap().read(&mut buffer);
|
||||
let command = Commands::from(&buffer);
|
||||
if command == Commands::Success(None) {
|
||||
break 'retry_loop1;
|
||||
}
|
||||
}
|
||||
},
|
||||
Ok(Commands::Client(Some(params))) => {
|
||||
let retry: u8 = 3;
|
||||
'retry_loop2: loop {
|
||||
if retry < 1 {
|
||||
self.transmit_data(Commands::Error(None).to_string().as_str());
|
||||
break 'retry_loop2;
|
||||
}
|
||||
self.transmit_data(Commands::Client(Some(params.clone())).to_string().as_str());
|
||||
let _ = self.stream_arc.lock().unwrap().read(&mut buffer);
|
||||
let command = Commands::from(&buffer);
|
||||
if command == Commands::Success(None) {
|
||||
break 'retry_loop2;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Commands::Disconnect(None)) => {
|
||||
|
||||
}
|
||||
|
||||
Ok(Commands::ClientRemove(Some(params))) => { },
|
||||
Ok(Commands::Success(params)) => { self.transmit_data(Commands::Success(params).to_string().as_str()); },
|
||||
Ok(Commands::Client(Some(params))) => { self.transmit_data(Commands::Client(Some(params)).to_string().as_str()); },
|
||||
|
||||
/*sender disconnected*/
|
||||
Err(TryRecvError::Disconnected) => {
|
||||
self.server_sender.send(ServerMessages::RequestDisconnect(self.uuid.clone()));
|
||||
},
|
||||
/*no data available yet*/
|
||||
Err(TryRecvError::Empty) => {},
|
||||
|
|
@ -100,14 +116,18 @@ impl Client {
|
|||
println!("command");
|
||||
match command {
|
||||
Commands::Disconnect(None) => {
|
||||
self.server_sender.send(ServerMessages::RequestDisconnect(self.uuid.clone())).expect("sending message to server failed");
|
||||
self.server_sender.send(ServerMessages::Disconnect(self.uuid.clone())).expect("sending message to server failed");
|
||||
},
|
||||
Commands::HeartBeat(None) => {
|
||||
self.transmit_data(Commands::HeartBeat(None).to_string().as_str())
|
||||
*self.last_heartbeat.lock().unwrap() = Instant::now();
|
||||
let _ = stream.write_all(Commands::Success(None).to_string().as_bytes());
|
||||
},
|
||||
Commands::ClientUpdate(None) => {
|
||||
let _ = self.server_sender.send(ServerMessages::RequestUpdate(self.uuid.clone()));
|
||||
let _ = stream.write_all(Commands::Success(None).to_string().as_bytes());
|
||||
}
|
||||
_ => {
|
||||
|
||||
self.transmit_data(Commands::Error(None).to_string().as_str())
|
||||
let _ = stream.write_all(Commands::Error(None).to_string().as_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -120,10 +140,25 @@ impl Client {
|
|||
self.stream_arc.lock().unwrap().shutdown(Shutdown::Both).expect("shutdown call failed");
|
||||
}
|
||||
|
||||
pub fn transmit_data(&self, data: &str){
|
||||
pub fn transmit_data(&self, data: &str) {
|
||||
println!("Transmitting data: {}", data);
|
||||
|
||||
self.stream_arc.lock().unwrap().write_all(data.to_string().as_bytes()).unwrap();
|
||||
self.stream_arc.lock().unwrap().flush().unwrap();
|
||||
let error_result = self.stream_arc.lock().unwrap().write_all(data.to_string().as_bytes());
|
||||
if let Some(error) = error_result.err(){
|
||||
match error.kind() {
|
||||
// handle disconnections
|
||||
io::ErrorKind::NotConnected => {
|
||||
let _ = self.server_sender.send(ServerMessages::Disconnect(self.uuid.clone()));
|
||||
},
|
||||
_ => { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Client {
|
||||
fn drop(&mut self) {
|
||||
let _ = self.stream_arc.lock().unwrap().write_all(Commands::Disconnect(None).to_string().as_bytes());
|
||||
let _ = self.stream_arc.lock().unwrap().shutdown(Shutdown::Both);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ mod message;
|
|||
|
||||
use std::string::ToString;
|
||||
use std::collections::HashMap;
|
||||
use dashmap::DashMap;
|
||||
use std::borrow::Borrow;
|
||||
use regex::Regex;
|
||||
use std::ops::Index;
|
||||
|
|
@ -168,7 +167,7 @@ impl From<&str> for Commands {
|
|||
|
||||
for i in iter {
|
||||
let parameter = i.as_str().to_string();
|
||||
let mut parts:Vec<&str> = parameter.split(":").collect();
|
||||
let parts:Vec<&str> = parameter.split(":").collect();
|
||||
|
||||
map.insert(parts.index(0).to_string(), parts.index(1).to_string());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
extern crate regex;
|
||||
extern crate rayon;
|
||||
|
||||
use crate::{
|
||||
server::{
|
||||
client::client_profile::Client,
|
||||
|
|
@ -17,6 +14,9 @@ use std::{
|
|||
io
|
||||
};
|
||||
|
||||
use regex::Regex;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use log::info;
|
||||
|
||||
use crossbeam_channel::{Sender, Receiver, unbounded};
|
||||
|
|
@ -31,7 +31,7 @@ pub enum ServerMessages {
|
|||
#[allow(dead_code)]
|
||||
RequestInfo(String, String),
|
||||
#[allow(dead_code)]
|
||||
RequestDisconnect(String),
|
||||
Disconnect(String),
|
||||
#[allow(dead_code)]
|
||||
Shutdown,
|
||||
}
|
||||
|
|
@ -85,12 +85,12 @@ impl Server {
|
|||
|
||||
// set up listener and buffer
|
||||
let listener = TcpListener::bind(self.get_address())?;
|
||||
listener.set_nonblocking(true);
|
||||
listener.set_nonblocking(true)?;
|
||||
|
||||
let mut buffer = [0; 1024];
|
||||
|
||||
info!("server: spawning threads");
|
||||
thread::Builder::new().name("Server Thread".to_string()).spawn(move || {
|
||||
let _ = thread::Builder::new().name("Server Thread".to_string()).spawn(move || {
|
||||
'outer: loop {
|
||||
// get messages from the servers channel.
|
||||
info!("server: getting messages");
|
||||
|
|
@ -100,6 +100,7 @@ impl Server {
|
|||
// TODO: implement disconnecting all clients and shutting down the server
|
||||
info!("server: shutting down...");
|
||||
|
||||
|
||||
break 'outer;
|
||||
},
|
||||
_ => {}
|
||||
|
|
@ -107,14 +108,14 @@ impl Server {
|
|||
}
|
||||
|
||||
info!("server: checking for new connections");
|
||||
if let Ok((mut stream, addr)) = listener.accept() {
|
||||
stream.set_read_timeout(Some(Duration::from_millis(100))).unwrap();
|
||||
if let Ok((mut stream, _addr)) = listener.accept() {
|
||||
stream.set_read_timeout(Some(Duration::from_millis(10000))).unwrap();
|
||||
|
||||
let request = Commands::Request(None);
|
||||
//request.to_string();
|
||||
stream.write_all(&request.to_string().as_bytes());
|
||||
stream.flush();
|
||||
stream.read(&mut buffer).unwrap();
|
||||
let _ = stream.write_all(&request.to_string().as_bytes());
|
||||
let _ = stream.flush();
|
||||
let _ = stream.read(&mut buffer).unwrap();
|
||||
|
||||
let incoming_message = String::from(String::from_utf8_lossy(&buffer));
|
||||
let command = Commands::from(incoming_message);
|
||||
|
|
@ -127,7 +128,7 @@ impl Server {
|
|||
let username = data.get("name").unwrap();
|
||||
let address = data.get("host").unwrap();
|
||||
|
||||
info!("{}", format!("Server: new Client connection: addr = {}", address ));
|
||||
info!("{}", format!("Server: new Client connection: _addr = {}", address ));
|
||||
|
||||
let client = Client::new(stream, sender.clone(), uuid.clone(), username.clone(), address.clone());
|
||||
|
||||
|
|
@ -136,8 +137,10 @@ impl Server {
|
|||
let params: HashMap<String, String> = [(String::from("name"), username.clone()), (String::from("host"), address.clone()), (String::from("uuid"), uuid.clone())].iter().cloned().collect();
|
||||
let new_client = Commands::Client(Some(params));
|
||||
|
||||
client_map.lock().unwrap().iter().map(|(k, v)| v.sender.send(new_client.clone()));
|
||||
let _ = client_map.lock().unwrap().iter().map(|(_k, v)| v.sender.send(new_client.clone()));
|
||||
},
|
||||
|
||||
// TODO: - correct connection reset error when getting info.
|
||||
Commands::Info(None) => {
|
||||
info!("Server: info requested");
|
||||
let mut params: HashMap<String, String> = HashMap::new();
|
||||
|
|
@ -146,13 +149,13 @@ impl Server {
|
|||
|
||||
let command = Commands::Info(Some(params));
|
||||
|
||||
stream.write_all(&command.to_string().as_bytes());
|
||||
stream.flush();
|
||||
let _ = stream.write_all(&command.to_string().as_bytes());
|
||||
let _ = stream.flush();
|
||||
},
|
||||
_ => {
|
||||
info!("Server: Invalid command sent");
|
||||
stream.write_all(Commands::Error(None).to_string().as_bytes());
|
||||
stream.flush();
|
||||
let _ = stream.write_all(Commands::Error(None).to_string().as_bytes());
|
||||
let _ = stream.flush();
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -172,7 +175,7 @@ impl Server {
|
|||
|
||||
pub fn stop(&self) {
|
||||
info!("server: sending stop message");
|
||||
self.sender.send(ServerMessages::Shutdown);
|
||||
let _ = self.sender.send(ServerMessages::Shutdown);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
|
|
@ -212,8 +215,4 @@ impl Drop for Server {
|
|||
println!("server dropped");
|
||||
let _ = self.sender.send(ServerMessages::Shutdown);
|
||||
}
|
||||
}
|
||||
|
||||
struct ServerDelegate {
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue