Struct nbio::frame::FrameDuplex
source · pub struct FrameDuplex<S, DF, SF> { /* private fields */ }
Expand description
§FrameDuplex
Encapsulates a binary bi-directional streaming Session
, providing framing using the given SerializeFrame
and DeserializeFrame
traits.
The underlying Publish::PublishPayload
and Receive::ReceivePayload
must be [u8]
.
This effectively translates any Session<ReceivePayload=[u8], PublishPayload=[u8]>
to a Session<ReceivePayload=YourStruct, PublishPayload=YourStruct>
provided apporpriate SerializeFrame
and DeserializeFrame
impls.
§Drive
It is imperative that the drive
function be called regularly in this implementation.
This function is responsible for writing bytes from the internal write buffer to the underlying Session
.
§Publish Buffering
Frames passed into publish
are serialized using the SerializeFrame
impl and are copied to an internal circular buffer.
The internal circular buffer is initialized with a capacity given to the new
function.
If the entire frame is not able to fit in the remaining circular buffer space, none of the frame will be copied.
In this case, PublishOutcome::Incomplete
will be returned with a reference to the frame to be retried later.
The circular buffer will grow to fit frames that exceed the entire circular buffer capacity, but only when the buffer is empty. This allows for any sized frame to be successfuly published while avoiding the circular buffer growing the unreasonable sizes.
§Receive Buffering
Data is received from the underlying binary Receive
Session
into an internal Vec<u8>
.
Each call to receive will first check if the read buffer contains a full frame to be returned immediately.
The underlying Receive::receive
function will only be called when the read buffer is devoid of a full frame.
This avoids the buffer growing to an unreasonable size, as it will only ever grow to the size of a frame plus the next read size.
Implementations§
source§impl<S, DF, SF> FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + for<'a> Receive<ReceivePayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
impl<S, DF, SF> FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + for<'a> Receive<ReceivePayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
sourcepub fn new(
session: S,
deserialize_frame: DF,
serialize_frame: SF,
write_buffer_capacity: usize
) -> Self
pub fn new( session: S, deserialize_frame: DF, serialize_frame: SF, write_buffer_capacity: usize ) -> Self
Create a new FrameDuplex
§Parameters
session
: The underlying binarySession
deserialize_frame
: The strategy used to convert binary data to framed messagesserialize_frame
: The strategy used to convert framed messages to binary datawrite_buffer_capacity
: The capacity, in bytes, of the underlying circular buffer that holds serialized write frames
Trait Implementations§
source§impl<S, DF, SF> Debug for FrameDuplex<S, DF, SF>
impl<S, DF, SF> Debug for FrameDuplex<S, DF, SF>
source§impl<S, DF, SF> Flush for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + Flush + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
impl<S, DF, SF> Flush for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + Flush + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
source§impl<S, DF, SF> Publish for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
impl<S, DF, SF> Publish for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
§type PublishPayload<'a> = <SF as SerializeFrame>::SerializedFrame<'a>
type PublishPayload<'a> = <SF as SerializeFrame>::SerializedFrame<'a>
publish(..)
function.source§fn publish<'a>(
&mut self,
frame: Self::PublishPayload<'a>
) -> Result<PublishOutcome<Self::PublishPayload<'a>>, Error>
fn publish<'a>( &mut self, frame: Self::PublishPayload<'a> ) -> Result<PublishOutcome<Self::PublishPayload<'a>>, Error>
payload
to the session. Read moresource§impl<S, DF, SF> Receive for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + for<'a> Receive<ReceivePayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
impl<S, DF, SF> Receive for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + for<'a> Receive<ReceivePayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
§type ReceivePayload<'a> = <DF as DeserializeFrame>::DeserializedFrame<'a>
type ReceivePayload<'a> = <DF as DeserializeFrame>::DeserializedFrame<'a>
receive(..)
function.source§fn receive<'a>(
&'a mut self
) -> Result<ReceiveOutcome<Self::ReceivePayload<'a>>, Error>
fn receive<'a>( &'a mut self ) -> Result<ReceiveOutcome<Self::ReceivePayload<'a>>, Error>
payload
from the session.
This will return ReceiveOutcome::Payload
when data has been received.
ReceiveOutcome::Buffered
can be used to report that work was completed, but data is not ready.
This means that only [ReceiveOutcome::None
] should be used to indicate to a scheduler that yielding or idling is appropriate.source§impl<S, DF, SF> Session for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
impl<S, DF, SF> Session for FrameDuplex<S, DF, SF>where
S: for<'a> Publish<PublishPayload<'a> = &'a [u8]> + 'static,
DF: DeserializeFrame + 'static,
SF: SerializeFrame + 'static,
source§fn status(&self) -> SessionStatus
fn status(&self) -> SessionStatus
source§fn close(&mut self)
fn close(&mut self)
SessionStatus::Terminated
state immediately, performing any necessary immediately graceful close actions as appropriate. Read moresource§fn drive(&mut self) -> Result<DriveOutcome, Error>
fn drive(&mut self) -> Result<DriveOutcome, Error>
drive(..)
to be called continuously to completely publish and/or receive data.
This function will return DriveOutcome::Active
if work was done, indicating to any scheduler that more work may be pending.
When this function returns DriveOutcome::Idle
, only then should it indicate to a scheduler that yielding or idling is appropriate.