pub struct AsyncSession<P: Protocol> { /* private fields */ }Expand description
Async handle to a session running in a spawned tokio task.
Methods translate to commands sent over an internal channel and reply over a oneshot. Dropping the handle severs the connection from the consumer side; the spawned task exits on its next loop.
Drop is not graceful — for graceful shutdown call
AsyncSession::disconnect. Drop just severs the connection from
the consumer’s side; the reflector eventually times the link out
via inactivity.
Implementations§
Source§impl<P: Protocol> AsyncSession<P>
impl<P: Protocol> AsyncSession<P>
Sourcepub fn spawn(session: Session<P, Connected>, socket: Arc<UdpSocket>) -> Selfwhere
P: Send + 'static,
pub fn spawn(session: Session<P, Connected>, socket: Arc<UdpSocket>) -> Selfwhere
P: Send + 'static,
Spawn the session loop on the current tokio runtime and return a handle for controlling it.
The session must already be in the [Connected] state
(typically via Session::<P, Connecting>::promote after
observing [Event::Connected] from the handshake). The
socket must be bound (typically via UdpSocket::bind).
The loop runs until the handle is dropped, the consumer’s command channel closes, or a fatal I/O error occurs.
§Example
use std::sync::Arc;
use dstar_gateway::tokio_shell::AsyncSession;
use dstar_gateway_core::session::client::{Connected, DExtra, Session};
use tokio::net::UdpSocket;
let sock = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
let mut shell = AsyncSession::spawn(connected, sock);
while let Some(event) = shell.next_event().await {
println!("{event:?}");
}Sourcepub async fn next_event(&mut self) -> Option<Event<P>>
pub async fn next_event(&mut self) -> Option<Event<P>>
Pull the next event from the inbound stream.
Returns None once the session task has exited and the event
channel has been fully drained.
§Cancellation safety
This method is cancel-safe. It only awaits a tokio::sync::mpsc
receiver, which is documented as cancel-safe: dropping the future
leaves the channel in a clean state and any undelivered events
remain queued for the next call.
Sourcepub async fn send_header(
&mut self,
header: DStarHeader,
stream_id: StreamId,
) -> Result<(), ShellError>
pub async fn send_header( &mut self, header: DStarHeader, stream_id: StreamId, ) -> Result<(), ShellError>
Send a voice header and start a new outbound voice stream.
§Errors
ShellError::SessionClosedif the session task has exitedShellError::Coreif the encoder rejects the header
§Cancellation safety
This method is cancel-safe. The method enqueues a Command
on the command channel and awaits a oneshot reply. If the future
is dropped before the enqueue completes no command is sent; if
it is dropped after the enqueue the session task still executes
the command and the (now-orphaned) oneshot reply is simply
discarded. Either way the session state remains consistent.
Sourcepub async fn send_voice(
&mut self,
stream_id: StreamId,
seq: u8,
frame: VoiceFrame,
) -> Result<(), ShellError>
pub async fn send_voice( &mut self, stream_id: StreamId, seq: u8, frame: VoiceFrame, ) -> Result<(), ShellError>
Send a voice data frame.
§Errors
ShellError::SessionClosedif the session task has exitedShellError::Coreif the encoder rejects the frame
§Cancellation safety
This method is cancel-safe under the same rules as
Self::send_header. Dropping the future either before the
command is enqueued or after it has been dispatched leaves the
session in a coherent state; orphaning the oneshot reply is
harmless.
Sourcepub async fn send_eot(
&mut self,
stream_id: StreamId,
seq: u8,
) -> Result<(), ShellError>
pub async fn send_eot( &mut self, stream_id: StreamId, seq: u8, ) -> Result<(), ShellError>
Send a voice EOT and close the outbound stream.
§Errors
ShellError::SessionClosedif the session task has exitedShellError::Coreif the encoder rejects the EOT
§Cancellation safety
This method is cancel-safe under the same rules as
Self::send_header.
Sourcepub async fn disconnect(&mut self) -> Result<(), ShellError>
pub async fn disconnect(&mut self) -> Result<(), ShellError>
Request a graceful disconnect.
Sends an UNLINK to the reflector and returns when the loop
has enqueued it. The caller should continue polling
Self::next_event until [Event::Disconnected] arrives,
then drop the session.
§Errors
ShellError::SessionClosedif the session task has exited
§Cancellation safety
This method is not cancel-safe. Cancelling the future drives
a state-machine transition (Connected → Disconnecting) that
may be partially complete: the UNLINK may already be in the
outbox even though the reply oneshot has been dropped. Callers
that cancel disconnect() should treat the session as
indeterminate and drop the handle rather than attempting further
sends. For graceful shutdown, always await this method to
completion before dropping the session.