pub struct BidiStream<B, Req, RespView> { /* private fields */ }Expand description
A bidirectional streaming RPC in progress.
Returned from call_bidi_stream. Provides a send/close_send/message
API modeled on connect-go’s BidiStreamForClient.
§Half-duplex vs full-duplex
The Connect spec supports both. Half-duplex (send all, then receive all)
works on HTTP/1.1 and HTTP/2. Full-duplex (interleaved send/receive) requires
HTTP/2. This type does not distinguish — it’s the caller’s responsibility to
respect the protocol in use. On HTTP/1.1, calling message() before
close_send() will block until the request body is complete.
§Example
let mut stream = call_bidi_stream(&transport, &config, "svc", "method", CallOptions::default()).await?;
stream.send(request1).await?;
stream.send(request2).await?;
stream.close_send();
// `Ok(None)` means a clean end; a failed RPC surfaces as `Err`,
// so `?` is the complete error handling.
while let Some(msg) = stream.message().await? {
println!("got: {msg:?}");
}Implementations§
Source§impl<B, Req, RespView> BidiStream<B, Req, RespView>where
B: Body<Data = Bytes> + Send + Unpin,
B::Error: Display,
Req: Message + JsonSerialize,
RespView: MessageView<'static> + Send,
RespView::Owned: Message + JsonDeserialize,
impl<B, Req, RespView> BidiStream<B, Req, RespView>where
B: Body<Data = Bytes> + Send + Unpin,
B::Error: Display,
Req: Message + JsonSerialize,
RespView: MessageView<'static> + Send,
RespView::Owned: Message + JsonDeserialize,
Sourcepub async fn send(&mut self, msg: Req) -> Result<(), ConnectError>
pub async fn send(&mut self, msg: Req) -> Result<(), ConnectError>
Send a request message.
Returns an error if close_send was already
called, if the whole-call deadline has passed, or if the server has
closed the stream (the receiver half was dropped). In the latter
case, call message() to retrieve the server’s error.
Sourcepub fn close_send(&mut self)
pub fn close_send(&mut self)
Close the send side of the stream. Idempotent.
After this, only receiving is possible. For half-duplex use
(HTTP/1.1), this must be called before message().
Sourcepub async fn message<M>(
&mut self,
) -> Result<Option<StreamMessage<M>>, ConnectError>where
RespView: MessageView<'static, Owned = M>,
M: HasMessageView<View<'static> = RespView>,
pub async fn message<M>(
&mut self,
) -> Result<Option<StreamMessage<M>>, ConnectError>where
RespView: MessageView<'static, Owned = M>,
M: HasMessageView<View<'static> = RespView>,
Receive the next response message.
The first call awaits response headers (lazily, so full-duplex servers that wait for a request before sending headers don’t deadlock). Subsequent calls decode envelopes from the response body stream.
Returns Ok(None) only when the server finished cleanly; a
server error carried in the termination metadata is returned as
Err, sticky across calls — see ServerStream::message() for the
full contract.
Sourcepub fn headers(&self) -> Option<&HeaderMap>
pub fn headers(&self) -> Option<&HeaderMap>
Response headers. None until the first message()
call resolves them (i.e. until the response HEADERS frame arrives).
Sourcepub fn trailers(&self) -> Option<&HeaderMap>
pub fn trailers(&self) -> Option<&HeaderMap>
Trailing metadata. Only populated after message()
reports the end of the stream (Ok(None) or the terminal Err).
Sourcepub fn error(&self) -> Option<&ConnectError>
pub fn error(&self) -> Option<&ConnectError>
Terminal error that ended the stream, if any — a server error from
the END_STREAM envelope (Connect) or trailers (gRPC), or a
decode/transport/deadline failure. message()
already returns this same error, so most callers never need this
accessor; it exists for post-hoc inspection alongside
trailers().