diff --git a/CHANGELOG.md b/CHANGELOG.md index 00c9f8b..335f88d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New `list_kinds` command for filters. - New `source` command for scene items. - New `InputSettingsChanged` and `SourceFilterSettingsChanged` event. +- **BREAKING CHANGE:** Extend the connection config with a `connection_timeout` setting that allows to cancel the connection attempt after a set duration. The `Client::connect` method now defaults to a _30 second_ timeout. ### Removed diff --git a/src/client/mod.rs b/src/client/mod.rs index 67a1b89..c8f01a5 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -8,6 +8,7 @@ use std::{ atomic::{AtomicU64, Ordering}, Arc, }, + time::Duration, }; #[cfg(feature = "events")] @@ -133,6 +134,10 @@ where /// not be send to listeners anymore. #[cfg_attr(not(feature = "events"), allow(dead_code))] pub broadcast_capacity: Option, + /// Maximum wait time to establish a connection with the OBS instance. If this limit is + /// exceeded, the connection ([`Client::connect_with_config`]) call will cancel the attempt and + /// return an [`Error::Timeout`]. + pub connect_timeout: Duration, } const OBS_STUDIO_VERSION: Comparator = Comparator { @@ -169,6 +174,11 @@ where impl Client { /// Connect to a obs-websocket instance on the given host and port. + /// + /// # Errors + /// + /// Will return an [`Error::Timeout`] if the connection couldn't be established within **30 + /// seconds**. pub async fn connect( host: impl AsRef, port: u16, @@ -186,6 +196,7 @@ impl Client { #[cfg(feature = "tls")] tls: false, broadcast_capacity: None, + connect_timeout: Duration::from_secs(30), }) .await } @@ -196,13 +207,17 @@ impl Client { H: AsRef, P: AsRef, { - let (socket, _) = tokio_tungstenite::connect_async(format!( - "{}://{}:{}", - if config.tls() { "wss" } else { "ws" }, - config.host.as_ref(), - config.port - )) + let (socket, _) = tokio::time::timeout( + config.connect_timeout, + tokio_tungstenite::connect_async(format!( + "{}://{}:{}", + if config.tls() { "wss" } else { "ws" }, + config.host.as_ref(), + config.port + )), + ) .await + .map_err(|_| Error::Timeout)? .map_err(Error::Connect)?; let (mut write, mut read) = socket.split(); diff --git a/src/lib.rs b/src/lib.rs index f3befd4..7e2dae0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,6 +60,9 @@ pub enum Error { /// An error occurred while trying to connect to the web-socket. #[error("failed to connect to the obs-websocket plugin")] Connect(#[source] tokio_tungstenite::tungstenite::Error), + /// The set connection timeout was reached before the connection could be created. + #[error("timeout happened before the connection could be established")] + Timeout, /// The initial handshake with `obs-websocket` didn't succeed. #[error("failed to execute the handshake with obs-websocket")] Handshake(#[from] crate::client::HandshakeError),