Add drain method for WebSocket{,Context}

This allows the user to retrieve the content of the message
queue after the socket connection died.
pull/95/head
jean-airoldie 5 years ago
parent 345d262972
commit ed0010126a
  1. 50
      src/protocol/mod.rs

@ -110,6 +110,12 @@ impl<Stream> WebSocket<Stream> {
pub fn set_config(&mut self, set_func: impl FnOnce(&mut WebSocketConfig)) {
self.context.set_config(set_func)
}
/// Consume the websocket, returning the content of its message queue,
/// from most to least recently queued.
pub fn drain(self) -> Vec<Message> {
self.context.drain()
}
}
impl<Stream: Read + Write> WebSocket<Stream> {
@ -370,6 +376,22 @@ impl WebSocketContext {
}
self.write_pending(stream)
}
/// Consume the websocket context, returning its queued messages,
/// from most to least recently queued.
pub fn drain(mut self) -> Vec<Message> {
let mut messages = Vec::with_capacity(self.send_queue.len());
let send_queue = replace(&mut self.send_queue, VecDeque::new());
for frame in send_queue.into_iter().rev() {
// This should not error since we created those frames.
if let Some(message) = self._read_message_frame(frame).unwrap() {
messages.push(message);
}
}
messages
}
}
impl WebSocketContext {
@ -378,7 +400,22 @@ impl WebSocketContext {
where
Stream: Read + Write,
{
if let Some(mut frame) = self.frame.read_frame(stream, self.config.max_frame_size)? {
if let Some(frame) = self.frame.read_frame(stream, self.config.max_frame_size)? {
self._read_message_frame(frame)
} else {
// Connection closed by peer
match replace(&mut self.state, WebSocketState::Terminated) {
WebSocketState::ClosedByPeer | WebSocketState::CloseAcknowledged => {
Err(Error::ConnectionClosed)
}
_ => Err(Error::Protocol(
"Connection reset without closing handshake".into(),
)),
}
}
}
fn _read_message_frame(&mut self, mut frame: Frame) -> Result<Option<Message>> {
if !self.state.can_read() {
return Err(Error::Protocol(
"Remote sent frame after having sent a Close Frame".into(),
@ -491,17 +528,6 @@ impl WebSocketContext {
}
}
} // match opcode
} else {
// Connection closed by peer
match replace(&mut self.state, WebSocketState::Terminated) {
WebSocketState::ClosedByPeer | WebSocketState::CloseAcknowledged => {
Err(Error::ConnectionClosed)
}
_ => Err(Error::Protocol(
"Connection reset without closing handshake".into(),
)),
}
}
}
/// Received a close frame. Tells if we need to return a close frame to the user.

Loading…
Cancel
Save