mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-27 06:30:20 +00:00
handle liveview sockets disconnecting
This commit is contained in:
parent
e5e1abbdac
commit
1b53d4585e
2 changed files with 49 additions and 8 deletions
|
@ -5,6 +5,7 @@ use std::{
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use dioxus_core::Template;
|
||||||
pub use dioxus_hot_reload_macro::hot_reload;
|
pub use dioxus_hot_reload_macro::hot_reload;
|
||||||
use dioxus_html::HtmlCtx;
|
use dioxus_html::HtmlCtx;
|
||||||
use dioxus_rsx::hot_reload::{FileMap, UpdateResult};
|
use dioxus_rsx::hot_reload::{FileMap, UpdateResult};
|
||||||
|
@ -15,13 +16,30 @@ pub fn init(path: &'static str) {
|
||||||
if let Ok(crate_dir) = PathBuf::from_str(path) {
|
if let Ok(crate_dir) = PathBuf::from_str(path) {
|
||||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
let temp_file = std::env::temp_dir().join("@dioxusin");
|
||||||
let channels = Arc::new(Mutex::new(Vec::new()));
|
let channels = Arc::new(Mutex::new(Vec::new()));
|
||||||
|
let file_map = Arc::new(Mutex::new(FileMap::<HtmlCtx>::new(crate_dir.clone())));
|
||||||
if let Ok(local_socket_stream) = LocalSocketListener::bind(temp_file.as_path()) {
|
if let Ok(local_socket_stream) = LocalSocketListener::bind(temp_file.as_path()) {
|
||||||
// listen for connections
|
// listen for connections
|
||||||
std::thread::spawn({
|
std::thread::spawn({
|
||||||
|
let file_map = file_map.clone();
|
||||||
let channels = channels.clone();
|
let channels = channels.clone();
|
||||||
move || {
|
move || {
|
||||||
for connection in local_socket_stream.incoming() {
|
for connection in local_socket_stream.incoming() {
|
||||||
if let Ok(connection) = connection {
|
if let Ok(mut connection) = connection {
|
||||||
|
// send any templates than have changed before the socket connected
|
||||||
|
let templates: Vec<_> = {
|
||||||
|
file_map
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.map
|
||||||
|
.values()
|
||||||
|
.filter_map(|(_, template_slot)| *template_slot)
|
||||||
|
.collect()
|
||||||
|
};
|
||||||
|
for template in templates {
|
||||||
|
if !send_template(template, &mut connection) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
channels.lock().unwrap().push(connection);
|
channels.lock().unwrap().push(connection);
|
||||||
println!("Connected to hot reloading 🚀");
|
println!("Connected to hot reloading 🚀");
|
||||||
}
|
}
|
||||||
|
@ -32,7 +50,6 @@ pub fn init(path: &'static str) {
|
||||||
// watch for changes
|
// watch for changes
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let mut last_update_time = chrono::Local::now().timestamp();
|
let mut last_update_time = chrono::Local::now().timestamp();
|
||||||
let mut file_map = FileMap::<HtmlCtx>::new(crate_dir.clone());
|
|
||||||
|
|
||||||
let (tx, rx) = std::sync::mpsc::channel();
|
let (tx, rx) = std::sync::mpsc::channel();
|
||||||
|
|
||||||
|
@ -58,13 +75,21 @@ pub fn init(path: &'static str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// find changes to the rsx in the file
|
// find changes to the rsx in the file
|
||||||
match file_map.update_rsx(&path, crate_dir.as_path()) {
|
match file_map
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.update_rsx(&path, crate_dir.as_path())
|
||||||
|
{
|
||||||
UpdateResult::UpdatedRsx(msgs) => {
|
UpdateResult::UpdatedRsx(msgs) => {
|
||||||
for msg in msgs {
|
for msg in msgs {
|
||||||
for channel in channels.iter_mut() {
|
let mut i = 0;
|
||||||
let msg = serde_json::to_string(&msg).unwrap();
|
while i < channels.len() {
|
||||||
channel.write_all(msg.as_bytes()).unwrap();
|
let channel = &mut channels[i];
|
||||||
channel.write_all(&[b'\n']).unwrap();
|
if send_template(msg, channel) {
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
channels.remove(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,3 +107,17 @@ pub fn init(path: &'static str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_template(template: Template<'static>, channel: &mut impl Write) -> bool {
|
||||||
|
if let Ok(msg) = serde_json::to_string(&template) {
|
||||||
|
if channel.write_all(msg.as_bytes()).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if channel.write_all(&[b'\n']).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,9 @@ pub(crate) fn init(proxy: UnboundedSender<Template<'static>>) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let template: Template<'static> =
|
let template: Template<'static> =
|
||||||
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
||||||
proxy.send(template).unwrap();
|
if proxy.send(template).is_err() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if err.kind() != std::io::ErrorKind::WouldBlock {
|
if err.kind() != std::io::ErrorKind::WouldBlock {
|
||||||
|
|
Loading…
Reference in a new issue