Add example of detecting client drops in bidirectional streams on server side (#931)
This commit is contained in:
@@ -2,28 +2,85 @@ pub mod pb {
|
||||
tonic::include_proto!("grpc.examples.echo");
|
||||
}
|
||||
|
||||
use futures::stream::Stream;
|
||||
use std::time::Duration;
|
||||
use tokio_stream::StreamExt;
|
||||
use tonic::transport::Channel;
|
||||
|
||||
use pb::{echo_client::EchoClient, EchoRequest};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut client = EchoClient::connect("http://[::1]:50051").await.unwrap();
|
||||
fn echo_requests_iter() -> impl Stream<Item = EchoRequest> {
|
||||
tokio_stream::iter(1..usize::MAX).map(|i| EchoRequest {
|
||||
message: format!("msg {:02}", i),
|
||||
})
|
||||
}
|
||||
|
||||
async fn streaming_echo(client: &mut EchoClient<Channel>, num: usize) {
|
||||
let stream = client
|
||||
.server_streaming_echo(EchoRequest {
|
||||
message: "foo".into(),
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.into_inner();
|
||||
|
||||
// stream is infinite - take just 5 elements and then disconnect
|
||||
let mut stream = stream.take(num);
|
||||
while let Some(item) = stream.next().await {
|
||||
println!("\trecived: {}", item.unwrap().message);
|
||||
}
|
||||
// stream is droped here and the disconnect info is send to server
|
||||
}
|
||||
|
||||
async fn bidirectional_streaming_echo(client: &mut EchoClient<Channel>, num: usize) {
|
||||
let in_stream = echo_requests_iter().take(num);
|
||||
|
||||
let response = client
|
||||
.bidirectional_streaming_echo(in_stream)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
println!("Connected...now sleeping for 2 seconds...");
|
||||
let mut resp_stream = response.into_inner();
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
|
||||
while let Some(recived) = resp_stream.next().await {
|
||||
let recived = recived.unwrap();
|
||||
println!("\trecived message: `{}`", recived.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Disconnect
|
||||
drop(stream);
|
||||
drop(client);
|
||||
async fn bidirectional_streaming_echo_throttle(client: &mut EchoClient<Channel>, dur: Duration) {
|
||||
let in_stream = echo_requests_iter().throttle(dur);
|
||||
|
||||
println!("Disconnected...");
|
||||
let response = client
|
||||
.bidirectional_streaming_echo(in_stream)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let mut resp_stream = response.into_inner();
|
||||
|
||||
while let Some(recived) = resp_stream.next().await {
|
||||
let recived = recived.unwrap();
|
||||
println!("\trecived message: `{}`", recived.message);
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut client = EchoClient::connect("http://[::1]:50051").await.unwrap();
|
||||
|
||||
println!("Streaming echo:");
|
||||
streaming_echo(&mut client, 5).await;
|
||||
tokio::time::sleep(Duration::from_secs(1)).await; //do not mess server println functions
|
||||
|
||||
// Echo stream that sends 17 requests then gracefull end that conection
|
||||
println!("\r\nBidirectional stream echo:");
|
||||
bidirectional_streaming_echo(&mut client, 17).await;
|
||||
|
||||
// Echo stream that sends up to `usize::MAX` requets. One request each 2s.
|
||||
// Exiting client with CTRL+C demostrate how to distinguise broken pipe from
|
||||
//gracefull client disconnection (above example) on the server side.
|
||||
println!("\r\nBidirectional stream echo (kill client with CTLR+C):");
|
||||
bidirectional_streaming_echo_throttle(&mut client, Duration::from_secs(2)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user