Skip to main content

BidiStream

Struct BidiStream 

Source
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,

Source

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.

Source

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().

Source

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.

Source

pub fn headers(&self) -> Option<&HeaderMap>

Response headers. None until the first message() call resolves them (i.e. until the response HEADERS frame arrives).

Source

pub fn trailers(&self) -> Option<&HeaderMap>

Trailing metadata. Only populated after message() reports the end of the stream (Ok(None) or the terminal Err).

Source

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().

Trait Implementations§

Source§

impl<B, Req, RespView> Debug for BidiStream<B, Req, RespView>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<B, Req, RespView> !RefUnwindSafe for BidiStream<B, Req, RespView>

§

impl<B, Req, RespView> !UnwindSafe for BidiStream<B, Req, RespView>

§

impl<B, Req, RespView> Freeze for BidiStream<B, Req, RespView>

§

impl<B, Req, RespView> Send for BidiStream<B, Req, RespView>
where Req: Send, B: Send, RespView: Send,

§

impl<B, Req, RespView> Sync for BidiStream<B, Req, RespView>
where Req: Sync, B: Send + Sync, RespView: Sync,

§

impl<B, Req, RespView> Unpin for BidiStream<B, Req, RespView>
where Req: Unpin,

§

impl<B, Req, RespView> UnsafeUnpin for BidiStream<B, Req, RespView>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more