fix: automatically reconnect after losing a WebSocket connection
Some checks failed
actionlint check / actionlint check (pull_request) Successful in 5s
checkov check / checkov check (pull_request) Successful in 47s
conventional commit messages check / conventional commit messages check (pull_request) Successful in 5s
conventional pull request title check / conventional pull request title check (pull_request) Successful in 3s
dotenv-linter check / dotenv-linter check (pull_request) Successful in 5s
GitLeaks check / GitLeaks check (pull_request) Successful in 7s
hadolint check / hadolint check (pull_request) Successful in 7s
htmlhint check / htmlhint check (pull_request) Successful in 17s
markdownlint check / markdownlint check (pull_request) Successful in 18s
Prettier check / Prettier check (pull_request) Successful in 14s
Stylelint check / Stylelint check (pull_request) Successful in 1m15s
yamllint check / yamllint check (pull_request) Successful in 17s
Rust check / Rust check (pull_request) Has been cancelled
ShellCheck check / ShellCheck check (pull_request) Has been cancelled
Some checks failed
actionlint check / actionlint check (pull_request) Successful in 5s
checkov check / checkov check (pull_request) Successful in 47s
conventional commit messages check / conventional commit messages check (pull_request) Successful in 5s
conventional pull request title check / conventional pull request title check (pull_request) Successful in 3s
dotenv-linter check / dotenv-linter check (pull_request) Successful in 5s
GitLeaks check / GitLeaks check (pull_request) Successful in 7s
hadolint check / hadolint check (pull_request) Successful in 7s
htmlhint check / htmlhint check (pull_request) Successful in 17s
markdownlint check / markdownlint check (pull_request) Successful in 18s
Prettier check / Prettier check (pull_request) Successful in 14s
Stylelint check / Stylelint check (pull_request) Successful in 1m15s
yamllint check / yamllint check (pull_request) Successful in 17s
Rust check / Rust check (pull_request) Has been cancelled
ShellCheck check / ShellCheck check (pull_request) Has been cancelled
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use dioxus::{
|
||||
CapturedError,
|
||||
fullstack::{Loader, Loading, WebSocketOptions, use_websocket},
|
||||
fullstack::{Loader, Loading, WebSocketOptions},
|
||||
prelude::*,
|
||||
};
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
@@ -13,6 +13,29 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
fn use_on_document_become_visible(mut callback: impl FnMut() + 'static) {
|
||||
let callback = use_callback(move |_| callback());
|
||||
use_effect(move || {
|
||||
spawn(async move {
|
||||
let mut eval = document::eval(
|
||||
r#"
|
||||
document.addEventListener("visibilitychange", () => {
|
||||
if (!document.hidden) {
|
||||
dioxus.send(0);
|
||||
}
|
||||
});
|
||||
"#,
|
||||
);
|
||||
loop {
|
||||
eval.recv::<u8>()
|
||||
.await
|
||||
.expect("The JS code returned a value not parsable to `u8`.");
|
||||
callback.call(());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[allow(clippy::result_large_err)]
|
||||
fn sort_loader_result<T: Ord + Clone>(
|
||||
result: Result<Loader<Vec<T>>, Loading>,
|
||||
@@ -34,18 +57,38 @@ where
|
||||
E: Into<CapturedError> + 'static,
|
||||
{
|
||||
let mut refresh_tick = use_signal(|| 0u64);
|
||||
let mut websocket_reset_tick = use_signal(|| 0u64);
|
||||
|
||||
let loader = use_loader(move || {
|
||||
let _ = refresh_tick(); // Read => dependency.
|
||||
future()
|
||||
});
|
||||
|
||||
let mut socket = use_websocket(|| subscribe_to_updates(WebSocketOptions::default()));
|
||||
use_future(move || async move {
|
||||
use_effect(move || {
|
||||
let initial_websocket_reset_tick = websocket_reset_tick();
|
||||
spawn(async move {
|
||||
let Ok(socket) =
|
||||
subscribe_to_updates(WebSocketOptions::new().with_automatic_reconnect()).await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
while socket.recv().await.is_ok() {
|
||||
if websocket_reset_tick() != initial_websocket_reset_tick {
|
||||
// A new WebSocket has been created (a new task spawned), cleaning this one up.
|
||||
break;
|
||||
}
|
||||
refresh_tick += 1;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/* So that when the device goes to sleep or suspends the app, the WebSocket gets recreated on
|
||||
waking up. It is important to do this only on becoming visible (document.hidden == false),
|
||||
because becoming hidden is the part when network may not work and thus cause errors. */
|
||||
use_on_document_become_visible(move || {
|
||||
websocket_reset_tick += 1;
|
||||
refresh_tick += 1;
|
||||
});
|
||||
|
||||
loader
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user