From b441ca0015ab7139c36f31a8ad714a50fcb2986c Mon Sep 17 00:00:00 2001 From: Conner Date: Fri, 11 Oct 2024 10:49:14 +0200 Subject: [PATCH] esp-connect --- Cargo.lock | 19 +++++++++ Cargo.toml | 1 + crates/esp-connect/Cargo.toml | 7 ++++ crates/esp-connect/src/main.rs | 73 ++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 crates/esp-connect/Cargo.toml create mode 100644 crates/esp-connect/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index d425355..f3efbe2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1090,6 +1090,13 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "esp-connect" +version = "0.1.0" +dependencies = [ + "tokio", +] + [[package]] name = "etcetera" version = "0.8.0" @@ -3118,9 +3125,21 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", + "tokio-macros", "windows-sys 0.52.0", ] +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.79", +] + [[package]] name = "tokio-stream" version = "0.1.16" diff --git a/Cargo.toml b/Cargo.toml index 5b6961d..a0c2388 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,4 +5,5 @@ members = [ "crates/xtask", "crates/migration", "crates/entity", + "crates/esp-connect", ] diff --git a/crates/esp-connect/Cargo.toml b/crates/esp-connect/Cargo.toml new file mode 100644 index 0000000..e302556 --- /dev/null +++ b/crates/esp-connect/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "esp-connect" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "*", features = ["full"] } diff --git a/crates/esp-connect/src/main.rs b/crates/esp-connect/src/main.rs new file mode 100644 index 0000000..85f857a --- /dev/null +++ b/crates/esp-connect/src/main.rs @@ -0,0 +1,73 @@ +//! A "hello world" echo server with Tokio +//! +//! This server will create a TCP listener, accept connections in a loop, and +//! write back everything that's read off of each TCP connection. +//! +//! Because the Tokio runtime uses a thread pool, each TCP connection is +//! processed concurrently with all other TCP connections across multiple +//! threads. +//! +//! To see this server in action, you can run this in one terminal: +//! +//! cargo run --example echo +//! +//! and in another terminal you can run: +//! +//! cargo run --example connect 127.0.0.1:8080 +//! +//! Each line you type in to the `connect` terminal should be echo'd back to +//! you! If you open up multiple terminals running the `connect` example you +//! should be able to see them all make progress simultaneously. + +#![warn(rust_2018_idioms)] + +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::TcpListener; + +use core::str; +use std::env; +use std::error::Error; + +#[tokio::main] +async fn main() -> std::io::Result<()> { + // Allow passing an address to listen on as the first argument of this + // program, but otherwise we'll just set up our TCP listener on + // 127.0.0.1:8080 for connections. + let addr = String::from("0.0.0.0:7999"); + + // Next up we create a TCP listener which will listen for incoming + // connections. This TCP listener is bound to the address we determined + // above and must be associated with an event loop. + let listener = TcpListener::bind(&addr).await?; + println!("Listening on: {}", addr); + + loop { + // Asynchronously wait for an inbound socket. + let (mut socket, _) = listener.accept().await?; + println!("Connection Established"); + + // And this is where much of the magic of this server happens. We + // crucially want all clients to make progress concurrently, rather than + // blocking one on completion of another. To achieve this we use the + // `tokio::spawn` function to execute the work in the background. + // + // Essentially here we're executing a new task to run concurrently, + // which will allow all of our clients to be processed concurrently. + + let mut buf = vec![0; 1024]; + + // In a loop, read data from the socket and write the data back. + loop { + let n = socket + .read(&mut buf) + .await + .expect("failed to read data from socket"); + + if n == 0 { + return Ok(()); + } + + println!("{}", str::from_utf8(&buf).unwrap()) + } + } +}