pub struct WsSession { /* private fields */ }Expand description
An established JMAP WebSocket session (RFC 8887).
Call next_frame in a loop to receive events.
Use send_request to transmit JMAP requests.
The caller is responsible for reconnecting after the stream ends or returns a transport error. Use exponential backoff.
§Drop and cancellation (bd:JMAP-6r7c.24)
WsSession may be dropped at any point — including from inside a
tokio::select! losing branch while next_frame
is awaiting. Dropping is always safe and always synchronous:
- Partial frame state is discarded. The split sink and stream halves are owned by the session; dropping the session drops both halves and any in-flight tungstenite buffering.
- The underlying TCP / TLS connection is closed. No
Closeframe is sent — dropping skips the WebSocket close handshake. Callers that want the server to see a clean shutdown should arrange to receive the server’sClose(whichnext_framereturns asNone) before drop; this crate does not currently expose an explicit client-initiatedclose()method. - Resumption is the caller’s job. If you need to recover the
conversation state, you must either persist enough application-level
state to replay, or rely on the server’s push-state replay protocol.
WsSessionitself buffers nothing the caller can replay.
next_frame is cancel-safe in the sense that cancelling its future
(via select! or drop) does not corrupt subsequent calls to
next_frame on the same WsSession — but cancelling means giving up
on any partial frame that was being read; the next next_frame call
starts from the next complete message.
Implementations§
Source§impl WsSession
impl WsSession
Sourcepub async fn next_frame(&mut self) -> Option<Result<WsFrame, ClientError>>
pub async fn next_frame(&mut self) -> Option<Result<WsFrame, ClientError>>
Receive the next parsed frame from the server.
Delegates to WsReceiver::next_frame. Use this unified handle when
a single task drives both send and receive; for the
receive-loop-in-a-separate-task topology, call split
to get owned WsReceiver / WsSender halves.
Sourcepub async fn send_text(&mut self, text: String) -> Result<(), ClientError>
pub async fn send_text(&mut self, text: String) -> Result<(), ClientError>
Send a raw text frame over the WebSocket connection.
Delegates to WsSender::send_text.
Sourcepub async fn send_request(
&mut self,
req: &JmapRequest,
id: Option<&str>,
) -> Result<(), ClientError>
pub async fn send_request( &mut self, req: &JmapRequest, id: Option<&str>, ) -> Result<(), ClientError>
Send a JMAP request over the WebSocket connection.
Delegates to WsSender::send_request.
Sourcepub fn split(self) -> (WsSender, WsReceiver)
pub fn split(self) -> (WsSender, WsReceiver)
Consume the session and return its owned send and receive halves (bd:JMAP-6r7c.31).
Use this when a caller needs to drive the receive loop and the
send path concurrently — typically from two tokio::spawn-ed
tasks, one running a while let Some(...) = receiver.next_frame() .await loop and one occasionally sending requests via
sender.send_request(...). The unified WsSession API requires
&mut self for both directions and therefore cannot service them
concurrently; split is the explicit opt-in.
The two halves are independent owners of their tungstenite
sub-streams. Dropping one half does not close the connection until
the other half is also dropped (tungstenite’s WebSocketStream
only initiates the close handshake when both halves are gone). To
initiate a clean shutdown from a split session, drop the sender
after sending a final request and read from the receiver until it
returns None.