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?