Hi, I try to play a bit with async program in rust and I run into a issue.
So first here short version from the code wich get stuck at some point:
extern crate futures;
extern crate tokio;
use futures::{channel::mpsc, StreamExt};
use std::io::Error;
use tokio::{
net::{TcpListener, TcpStream},
sync::watch,
};
type Result<T> = core::result::Result<T, Error>;
type Receiver<T> = mpsc::UnboundedReceiver<T>;
type Watcher<T> = tokio::sync::watch::Receiver<T>;
#[tokio::main]
async fn main() -> Result<()> {
let addr = "127.0.0.1:50510".to_string();
let (sender, reader) = mpsc::unbounded::<u8>();
let (broadcaster, watcher) = watch::channel(0);
other_loop(reader).await;
accept_loop(addr, watcher).await
}
async fn other_loop(mut reader: Receiver<u8>) {
tokio::spawn(async move {
while let Some(_) = reader.next().await {}
});
}
async fn accept_loop(
addr: String,
watcher: Watcher<u8>,
) -> Result<()> {
let listener = TcpListener::bind(&addr).await?;
let mut incoming = listener.incoming();
println!("Listening on: {}", addr);
while let Some(stream) = incoming.next().await {
let stream = stream?;
let receiver = watcher.clone();
println!("Accepting from: {}", stream.peer_addr()?);
tokio::spawn(async move {
connection_loop(receiver, stream).await;
});
}
Ok(())
}
async fn connection_loop(
mut receiver: Watcher<u8>,
stream: TcpStream,
) {
while let Some(_) = receiver.recv().await {
};
}
So I run it then some clients connect to the server and the first two are ok but then no more clients are accepted. On the real code I've a version where everything is ok just by putting code from other_loop directly into the main.
I don't understand what can go wrong so I hope someone can help me
Ok thanks both of you for syntaxic tips but I should precise that the multiple clients try to connect almost simultaneous.
I am able to reproduce the problem with a firefox where I spam "Ctrl + t", "Ctrl + v", "Enter" with the address ready to be paste ( Yeah not really nice way to create clients, but it work ).
The first X clients are accepted, then nothing.
I come back with news, the code post here work fine my issue was something else (and @alice you are right about firefox ).
I try different syntax base on examples that you give to me and removing my tokio::spawn(async move {}) from inside my function to put it outside just work.
The real code is bigger so I don't post it.
I still don't fully understand the problem but I will try to learn more about tokio task.