- Notifications
You must be signed in to change notification settings - Fork341
Open
Description
Documentation
Async chat server example is usingconnection_writer_loop()
task to ensure, that client messages will not be interleaved.https://book.async.rs/tutorial/sending_messages
What ifbroker_loop()
will send client messages back toconnection_loop()
instead of creatingconnection_writer_loop()
and passingAcr<TcpStram>
all around? This can IMO lead to cleaner design, what is always good in tutorial. AlsoAcr<TcpStram>
is not necessary then, because TcpStream never escapesconnection_loop()
. We can also uselet (socket_reader, mut socket_writer) = (&stream, &stream);
pattern here.
We can then write something like this:
asyncfnconnection_loop(client_id:i32,broker:Sender<ClientEvent>,stream:TcpStream) ->Result<()>{let(socket_reader,mut socket_writer) =(&stream,&stream);let reader =BufReader::new(socket_reader);letmut lines = reader.lines();let name =match lines.next().await{None =>Err("peer disconnected immediately")?,Some(line) => line?,}; broker.send(Event::NewPeer{name: name.clone(),stream:Arc::clone(&stream)}).await// 3.unwrap();let(peer_sender, peer_receiver) = channel::unbounded::<String>(); broker.send(ClientEvent::NewPeer{ client_id,sender: peer_sender,}).await.unwrap();loop{select!{ line = lines.next().fuse() =>{let line = line?;let(dest, msg) =match line.find(':'){None =>continue,Some(idx) =>(&line[..idx], line[idx +1 ..].trim()),};let dest:Vec<String> = dest.split(',').map(|name| name.trim().to_string()).collect();let msg:String = msg.to_string(); broker.send(Event::Message{// 4 from: name.clone(), to: dest, msg,}).await.unwrap();}, message = peer_receiver.next().fuse() =>match message{None =>{break;}Some(message) =>{ socket_writer.send(msg.as_bytes()).await?;}}}} broker.send(ClientEvent::PeerGone{ client_id}).await.unwrap();Ok(())}
Metadata
Metadata
Assignees
Labels
No labels