stream-reconnect

crates.io Documentation

This crate provides a Stream/Sink-wrapping struct that automatically recover from potential disconnections/interruptions.

This is a fork of stubborn-io, which is built for the same purpose but for AsyncRead/AsyncWrite.

To use with your project, add the following to your Cargo.toml:

toml stream-reconnect = "0.3"

Runtime Support

This crate supports both tokio and async-std runtime.

tokio support is enabled by default. While used on an async-std runtime, change the corresponding dependency in Cargo.toml to

toml stream-reconnect = { version = "0.3", default-features = false, features = ["async-std"] }

Example

In this example, we will see a drop in replacement for tungstenite's WebSocketStream, with the distinction that it will automatically attempt to reconnect in the face of connectivity failures.

```rust struct MyWs(WebSocketStream>);

// implement Stream & Sink for MyWs

impl UnderlyingStream for MyWs { // Establishes connection. // Additionally, this will be used when reconnect tries are attempted. fn establish(addr: String) -> Pin> + Send>> { Box::pin(async move { // In this case, we are trying to connect to the WebSocket endpoint let wsconnection = connectasync(addr).await.unwrap().0; Ok(MyWs(ws_connection)) }) }

// The following errors are considered disconnect errors.
fn is_write_disconnect_error(&self, err: &WsError) -> bool {
    matches!(
            err,
            WsError::ConnectionClosed
                | WsError::AlreadyClosed
                | WsError::Io(_)
                | WsError::Tls(_)
                | WsError::Protocol(_)
        )
}

// If an `Err` is read, then there might be an disconnection.
fn is_read_disconnect_error(&self, item: &Result<Message, WsError>) -> bool {
    if let Err(e) = item {
        self.is_write_disconnect_error(e)
    } else {
        false
    }
}

// Return "Exhausted" if all retry attempts are failed.
fn exhaust_err() -> WsError {
    WsError::Io(io::Error::new(io::ErrorKind::Other, "Exhausted"))
}

}

type ReconnectWs = ReconnectStream, WsError>;

[tokio::main]

async fn main() { let mut wsstream: ReconnectWs = ReconnectWs::connect(String::from("wss://localhost:8000")); wsstream.send("hello world!").await.unwrap(); } ```

License

MIT