Skip to content

Instantly share code, notes, and snippets.

@ddprrt

ddprrt/main-3.rs Secret

Last active February 4, 2023 22:04
Show Gist options
  • Save ddprrt/750d9c9ca29ae92c8b4a58106c0e5f22 to your computer and use it in GitHub Desktop.
Save ddprrt/750d9c9ca29ae92c8b4a58106c0e5f22 to your computer and use it in GitHub Desktop.
Tokio Hello World + Task
use std::{net::SocketAddr, future::Future, task::Poll, time::{Instant, Duration}};
use tokio::{
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
net::TcpListener,
sync::broadcast,
};
#[tokio::main]
async fn main() -> tokio::io::Result<()> {
let listener = TcpListener::bind("localhost:8001").await?;
let (tx, _rx) = broadcast::channel::<(SocketAddr, String)>(100);
loop {
let (mut socket, addr) = listener.accept().await?;
println!("Listening to {}", addr);
let tx = tx.clone();
let mut rx = tx.subscribe();
tokio::spawn(async move {
let (reader, mut writer) = socket.split();
let mut reader = BufReader::new(reader);
loop {
let mut buffer = String::new();
tokio::select! {
// Reads from Channel, Sends to Socket
msg = rx.recv() => {
let (other_addr, msg) = msg.unwrap();
if other_addr != addr {
writer.write_all(format!("{}: {}", other_addr, msg).as_bytes()).await.unwrap();
}
}
// Reads from Socket, sends to Channel
result = reader.read_line(&mut buffer) => {
if result.is_err() || buffer.trim() == "exit" {
println!("Disconnected, {}", addr);
break;
}
tx.send((addr, buffer)).unwrap();
}
}
}
});
}
}
use std::{net::SocketAddr, future::Future, task::Poll, time::{Instant, Duration}};
use tokio::{
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
net::TcpListener,
sync::broadcast,
};
#[tokio::main]
async fn main() -> tokio::io::Result<()> {
loop {
tokio::select! {
a = MyFuture{} => {
println!("First branch, {:?}", a);
}
b = MyFuture{} => {
println!("Second branch, {:?}", b);
}
}
tokio::time::sleep(Duration::from_millis(1000)).await;
}
}
struct MyFuture;
impl Future for MyFuture {
type Output = Instant;
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<Self::Output> {
let instant = Instant::now();
println!("From Future: {:?}", instant);
Poll::Ready(instant)
}
}
use tokio::{
io::{AsyncWriteExt, BufReader, AsyncBufReadExt},
net::TcpListener,
};
#[tokio::main]
async fn main() -> tokio::io::Result<()> {
let listener = TcpListener::bind("localhost:8001").await?;
loop {
let (mut socket, addr) = listener.accept().await?;
println!("Listening to {}", addr);
tokio::spawn(async move {
loop {
let (reader, mut writer) = socket.split();
let mut reader = BufReader::new(reader);
let mut buffer = String::new();
if reader.read_line(&mut buffer).await.is_err() || buffer.trim() == "exit" {
println!("Disconnected, {}", addr);
break;
}
writer.write_all(buffer.as_bytes()).await.unwrap();
}
});
}
}
use tokio::{
io::{self, AsyncWriteExt},
net::TcpListener,
};
#[tokio::main]
async fn main() -> io::Result<()> {
let listener = TcpListener::bind("localhost:8001").await?;
loop {
let (mut socket, addr) = listener.accept().await?;
println!("Listening to {}", addr);
tokio::spawn(async move { socket.write_all("Hello World!\n\r".as_bytes()).await });
}
}

Chat server

Advance your echo server to a telnet based chat! Your chat server…

  • Accepts multiple connections
  • Broadcasts every message to all available connections Stretch goals
  • Make sure you don't broadcast your message to yourself

Create an echo server

  • Create a server with Tokio that allows for incoming connections
  • The server…
    • Accepts connections
    • Reads incoming messages
    • Sends the messages immediately back to the client
  • Stretch goals
    • Handle multiple connections simultaneously

Test with `telnet localhost:8001

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment