Rust Hyper streaming capability

Viewed 1022

I'm currently trying to achieve data streaming trough a simple HTTP get request in rust with hyper (0.13). The idea is simple. If the client sends a request the server responds in "chunks" every 5s leaving the connection open the whole time.

I'm trying to implement the trait Stream from futures crate

impl Stream for MonitorString {
    type Item = Result<String, serde_json::Error>;

    fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Result<String, serde_json::Error>>> {
        thread::sleep(Duration::from_secs(5)); 

        Poll::Ready(Some(self.data.to_string()))
    }
}

Then build a response like

type StreamingServiceResult = Result<Response<Body>, Box<dyn std::error::Error + Sync + Send>>;

pub async fn handle_request(_: Request<Body>, params: Params, _: Query) -> StreamingServiceResult {
     Ok(Response::builder()
        .header(hyper::header::CONTENT_TYPE, "application/json")
        .header(hyper::header::ACCESS_CONTROL_ALLOW_ORIGIN, "*")
        .header(hyper::header::TRANSFER_ENCODING, "chunked")
        .body(Body::wrap_stream(MonitorString::new(...)))
}

When I send a request the server, it opens the connection and hangs. With some debugging I saw that the poll_next function is called, but the response is only sent when the Stream has nothing more to yield (Poll::Ready(None) is returned by poll_next) and is sent in the whole.

I can see that my initial understanding of the Stream trait and Body::wrap_stream was wrong. Sadly I couldn't find any examples that works for my use-case. Can you put me on the right track with this one?

0 Answers
Related