chore(tcp): use tcp from tokio instead of std

This commit is contained in:
MedzikUser 2022-07-01 21:32:20 +02:00
parent cb1ccc6fc5
commit f08093ecc7
No known key found for this signature in database
GPG Key ID: A5FAC1E185C112DB
7 changed files with 24 additions and 24 deletions

View File

@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
<!-- next-header --> <!-- next-header -->
## [Unreleased] ## [Unreleased]
## Chore
- **tcp**: use tcp from tokio instead of std
## [0.2.0] - 2022-06-26 ## [0.2.0] - 2022-06-26
### Features ### Features

View File

@ -39,7 +39,7 @@ impl Command for PluginTest {
_args: Vec<&str>, _args: Vec<&str>,
_commands: &PluginManagerType, _commands: &PluginManagerType,
) -> Result<()> { ) -> Result<()> {
client.send("content")?; client.send("content").await?;
Ok(()) Ok(())
} }
@ -55,7 +55,7 @@ impl Event for PluginTest {
/// Event function /// Event function
async fn execute(&self, client: &mut Client) -> Result<()> { async fn execute(&self, client: &mut Client) -> Result<()> {
client.send(&format!("Welcome {}", client.stream.peer_addr().unwrap()))?; client.send(&format!("Welcome {}", client.stream.peer_addr().unwrap())).await?;
Ok(()) Ok(())
} }

View File

@ -24,7 +24,7 @@ impl Command for CommandHelp {
plugin_manager: &PluginManagerType, plugin_manager: &PluginManagerType,
) -> Result<()> { ) -> Result<()> {
for command in plugin_manager.commands.iter() { for command in plugin_manager.commands.iter() {
client.send(&format!("{} - {}", command.name(), command.help()))?; client.send(&format!("{} - {}", command.name(), command.help())).await?;
} }
Ok(()) Ok(())

View File

@ -1,4 +1,4 @@
use std::{fs::File, net::TcpListener}; use std::fs::File;
use clap::Parser; use clap::Parser;
use log::{error, info, LevelFilter}; use log::{error, info, LevelFilter};
@ -7,6 +7,7 @@ use servers::{
tcp::{handle_connection, handle_websocket, Client}, tcp::{handle_connection, handle_websocket, Client},
}; };
use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger}; use simplelog::{ColorChoice, CombinedLogger, Config, TermLogger, TerminalMode, WriteLogger};
use tokio::net::TcpListener;
#[derive(Parser)] #[derive(Parser)]
#[clap( #[clap(
@ -88,7 +89,7 @@ async fn main() -> anyhow::Result<()> {
/// Start tcp server /// Start tcp server
async fn start_tcp_server(host: String, port: String) -> anyhow::Result<()> { async fn start_tcp_server(host: String, port: String) -> anyhow::Result<()> {
// listen Tcp server // listen Tcp server
let listener = TcpListener::bind(format!("{host}:{port}"))?; let listener = TcpListener::bind(format!("{host}:{port}")).await?;
info!("Tcp server started at: {}", listener.local_addr()?); info!("Tcp server started at: {}", listener.local_addr()?);
@ -96,7 +97,7 @@ async fn start_tcp_server(host: String, port: String) -> anyhow::Result<()> {
let plugin_manager = loader()?; let plugin_manager = loader()?;
// Accepts a new incoming connection from this listener. // Accepts a new incoming connection from this listener.
while let Ok((stream, _address)) = listener.accept() { while let Ok((stream, _address)) = listener.accept().await {
let client = Client::new(stream); let client = Client::new(stream);
let plugin_manager = plugin_manager.clone(); let plugin_manager = plugin_manager.clone();

View File

@ -85,7 +85,7 @@
//! //!
//! /// Command function //! /// Command function
//! async fn execute(&self, client: &mut Client, _args: Vec<&str>, _commands: &PluginManagerType) -> Result<()> { //! async fn execute(&self, client: &mut Client, _args: Vec<&str>, _commands: &PluginManagerType) -> Result<()> {
//! client.send("Command executed!")?; //! client.send("Command executed!").await?;
//! //!
//! Ok(()) //! Ok(())
//! } //! }
@ -135,7 +135,8 @@
//! /// Event function //! /// Event function
//! async fn execute(&self, client: &mut Client) -> Result<()> { //! async fn execute(&self, client: &mut Client) -> Result<()> {
//! client //! client
//! .send(&format!("Welcome {}", client.stream.peer_addr().unwrap()))?; //! .send(&format!("Welcome {}", client.stream.peer_addr()?))
//! .await?;
//! //!
//! Ok(()) //! Ok(())
//! } //! }

View File

@ -1,13 +1,10 @@
#![allow(clippy::unused_io_amount)] #![allow(clippy::unused_io_amount)]
use tokio::{net::TcpStream, io::{self, AsyncWriteExt, AsyncReadExt}};
/// Max size of a TCP packet /// Max size of a TCP packet
pub const MAX_PACKET_LEN: usize = 65536; pub const MAX_PACKET_LEN: usize = 65536;
use std::{
io::{self, Read, Write},
net::TcpStream,
};
/// TCP Client /// TCP Client
pub struct Client { pub struct Client {
/// TCP stream of this client /// TCP stream of this client
@ -21,12 +18,12 @@ impl Client {
} }
/// Read message/buffer from client /// Read message/buffer from client
pub fn read(&mut self) -> anyhow::Result<String> { pub async fn read(&mut self) -> anyhow::Result<String> {
// allocate an empty buffer // allocate an empty buffer
let mut buf = [0; MAX_PACKET_LEN]; let mut buf = [0; MAX_PACKET_LEN];
// read buffer from stream // read buffer from stream
let len = self.stream.read(&mut buf)?; let len = self.stream.read(&mut buf).await?;
// select only used bytes from the buffer // select only used bytes from the buffer
let recv_buf = &buf[0..len]; let recv_buf = &buf[0..len];
@ -38,11 +35,11 @@ impl Client {
} }
/// Send message to client /// Send message to client
pub fn send(&mut self, content: &str) -> io::Result<()> { pub async fn send(&mut self, content: &str) -> io::Result<()> {
// add a new line at the end of the content // add a new line at the end of the content
let content = format!("{content}\n\r"); let content = format!("{content}\n\r");
// send message // send message
self.stream.write_all(content.as_bytes()) self.stream.write_all(content.as_bytes()).await
} }
} }

View File

@ -1,6 +1,5 @@
use std::io::Write;
use log::{error, info, trace}; use log::{error, info, trace};
use tokio::io::AsyncWriteExt;
use crate::plugins::PluginManagerType; use crate::plugins::PluginManagerType;
@ -18,7 +17,7 @@ pub async fn handle_connection(
loop { loop {
// read client message/buffer // read client message/buffer
let buf = client.read()?; let buf = client.read().await?;
// run `onSend` events from plugins // run `onSend` events from plugins
check_event(&mut client, &plugin_manager, "onSend").await?; check_event(&mut client, &plugin_manager, "onSend").await?;
@ -28,7 +27,7 @@ pub async fn handle_connection(
// client sent an empty buffer // client sent an empty buffer
if args.is_empty() { if args.is_empty() {
client.send("empty buffer")?; client.send("empty buffer").await?;
// don't execute the following commands because it causes panic // don't execute the following commands because it causes panic
continue; continue;
@ -52,7 +51,7 @@ pub async fn handle_connection(
Err(err) => { Err(err) => {
error!("failed to execute command `{cmd}`, error message = `{err}`"); error!("failed to execute command `{cmd}`, error message = `{err}`");
client.send(&format!("error: {err}"))?; client.send(&format!("error: {err}")).await?;
} }
} }
@ -62,7 +61,7 @@ pub async fn handle_connection(
} }
// if an I/O or EOF error, abort the connection // if an I/O or EOF error, abort the connection
if client.stream.flush().is_err() { if client.stream.flush().await.is_err() {
// terminate connection // terminate connection
break; break;
} }
@ -88,7 +87,7 @@ async fn check_event(
Err(err) => { Err(err) => {
error!("failed to execute event `{event_name}`, error message = `{err}`"); error!("failed to execute event `{event_name}`, error message = `{err}`");
client.send(&format!("error: {err}"))?; client.send(&format!("error: {err}")).await?;
} }
} }
} }