Expand description
A wrapper around WebSocket that reconnects when the socket
drops. Uses Backoff to determine the delay between reconnects
§Features
tracing- enables thetracingcrate and logs everything it’s doingstate-events- changes the Item type of the stream to be an enum that is either a message or a status change Both are enabled by default
§Usage
Input means stuff you want to send from this client to the server
Outut means stuff you want to receive back from the server
- Implement
TryFromforMessagefor your input type- The
TryFrom::Errortype must implementDebug
- The
- Implement
TryFrom<Message>for your output type- The
TryFrom::Errortype must implementDebug
- The
- Both input and output need to implement
Unpinand, if using tracing feature,Debug - Use
SocketBuilderto set the URL and configure backoff.get_proto_and_hostcan help constructing the URL relative to the currentwindow.location - Call
SocketBuilder::opento connect the socket. The errorsopenreturns are likely fatal (invalid URL, blocked port), seeWebSocket::openfor details. The first connect is done in the builder so it fails fast if these fatal errors occur but the same kind of error can also occur on any reconnect and be returned by theSocketStreamimplementation - The returned
Socketcan then be polled to get incoming messages.Socket::sendcan be called to send messages or [Socket::get_sender] can be used to get anUnboundedSender.Socket::closeor dropping it will drop the innerWebSocketwhich sends a close frame and cleans up the event handlers
§Example
tests/reconnect.rs
use cfg_if::cfg_if;
use futures::{select, FutureExt, StreamExt};
use gloo::timers::future::TimeoutFuture;
#[cfg(feature = "state-events")]
use reconnecting_websocket::Event;
use reconnecting_websocket::{Socket, SocketBuilder};
#[path = "./common.rs"]
mod common;
use common::{configure_tracing_once, Input, Output, ECHO_SERVER};
use tracing::{error, info};
#[cfg(all(test, target_arch = "wasm32"))]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
#[cfg(test)]
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
async fn reconnect() {
use reconnecting_websocket::Error;
use tracing::trace;
const SEND_COUNT: usize = 10;
configure_tracing_once();
async fn send_messages(socket: &mut Socket<Input, Output>, count: usize) {
let mut outstanding_packets = Vec::new();
for i in 0..count {
outstanding_packets.push(i);
socket.send(Input::Bar(i)).await.expect("send");
}
let mut timeout = TimeoutFuture::new(5000).fuse();
loop {
select! {
r = socket.next() => {
let r = r.expect("next None");
fn handle_message(o: Result<Output, Error<Input, Output>>, outstanding_packets: &mut Vec<usize>) {
match o {
Ok(Output::Foo(n)) => {
trace!("Output::Foo({n})");
outstanding_packets.retain(|v| *v != n);
},
Err(e) => {
error!("next err: {e:?}");
}
}
}
cfg_if! {
if #[cfg(feature = "state-events")] {
match r {
Event::Message(m) => handle_message(m, &mut outstanding_packets),
Event::State(s) => info!("State changed: {s:?}"),
}
} else {
handle_message(r, &mut outstanding_packets);
}
}
if outstanding_packets.len() == 0 {
break;
}
},
_ = timeout => {
panic!("Timed out before receiving all responses (outstanding: {outstanding_packets:?}");
},
}
}
}
let mut socket = SocketBuilder::<Input, Output>::new(ECHO_SERVER.to_string()).open().unwrap();
info!("First test (before reconnect)");
send_messages(&mut socket, SEND_COUNT).await;
// Drop the socket
socket.close_socket(None, Some("test close"));
info!("Second test (after reconnect)");
send_messages(&mut socket, SEND_COUNT).await;
info!("All done");
}Structs§
- Socket
- A wrapper around
WebSocketthat reconnects when the socket drops. UsesBackoffto determine the delay between reconnects - Socket
Builder - Builder for
SocketUses the DEFAULT_* consts for backoff and retry config - Socket
Sink - A handle that implements
Sinkfor sending messages from the client to the server
Enums§
- Error
- Errors returned by
crate::Socketandcrate::SocketBuilder - Event
futures::Stream::Itemtype forcrate::Socketwhenstate-eventsfeature is enabled- Http
Protocol - The protocol extracted from
window.location - Message
- Re-export of
gloo::net::websocket::Message. Message sent to and received from WebSocket. - State
- The state of the websocket.
- WebSocket
Protocol - A websocket protocol
Constants§
- DEFAULT_
BACKOFF_ MAX - The maximum delay for exponential backoff
See
exponential_backoff::Backofffor details Must be <= u32::MAX millis - DEFAULT_
BACKOFF_ MIN - The minimum delay for exponential backoff
See
exponential_backoff::Backofffor details Must be > 0 millis - DEFAULT_
MAX_ RETRIES - The maximum number of retries. The stream will close after this is exceeded
Traits§
- Socket
Input - Trait expressing the requirements for a socket input type
You don’t need to implement it directly, there is a blanked implementation for types that implement
Unpin,Debug, <MessageasTryFrom<Self>> - Socket
Output - Trait expressing the requirements for a socket output type
You don’t need to implement it directly, there is a blanked implementation for types that implement
Unpin,Debug, <SelfasTryFrom<Message>>
Functions§
- get_
proto_ and_ host - Helper function to get the protocol and host from
window.location