Explorar el Código

fix: auto-connect `ws` server

mrxiaozhuox hace 3 años
padre
commit
7aeddba427
Se han modificado 2 ficheros con 77 adiciones y 74 borrados
  1. 19 21
      src/assets/autoreload.js
  2. 58 53
      src/server/mod.rs

+ 19 - 21
src/assets/autoreload.js

@@ -1,24 +1,22 @@
 (function () {
-  var protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
-
-  var url = protocol + "//" + window.location.host + "/_dioxus/ws";
-
-  var poll_interval = 2000;
+  var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
+  var url = protocol + '//' + window.location.host + '/_dioxus/ws';
+  var poll_interval = 8080;
+  var reload_upon_connect = () => {
+      window.setTimeout(
+          () => {
+              var ws = new WebSocket(url);
+              ws.onopen = () => window.location.reload();
+              ws.onclose = reload_upon_connect;
+          },
+          poll_interval);
+  };
 
   var ws = new WebSocket(url);
-
-  ws.addEventListener("message", (ev) => {
-    if (ev.data == "reload") {
-      window.location.reload();
-    }
-  });
-  
-  ws.addEventListener("open", () => {
-    ws.send("init");
-  });
-
-  ws.addEventListener("close", () => {
-    alert("Dev-Server Socket Closed.");
-  });
-
-})();
+  ws.onmessage = (ev) => {
+      if (ev.data == "reload") {
+          window.location.reload();
+      }
+  };
+  ws.onclose = reload_upon_connect;
+})()

+ 58 - 53
src/server/mod.rs

@@ -36,6 +36,7 @@ pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
         .watch_path
         .clone()
         .unwrap_or_else(|| vec![PathBuf::from("src")]);
+
     for sub_path in allow_watch_path {
         watcher
             .watch(
@@ -46,60 +47,63 @@ pub async fn startup(config: CrateConfig) -> anyhow::Result<()> {
     }
 
     let (reload_tx, _) = broadcast::channel(100);
-    let ws_reload_state = Arc::new(WsRelodState { update: reload_tx });
+
+    let ws_reload_state = Arc::new(WsRelodState {
+        update: reload_tx.clone(),
+    });
 
     let watcher_conf = config.clone();
-    let watcher_ws_state = ws_reload_state.update.clone();
+
     tokio::spawn(async move {
-        loop {
-            if let Ok(v) = watcher_rx.recv() {
-                match v {
-                    DebouncedEvent::Create(_)
-                    | DebouncedEvent::Write(_)
-                    | DebouncedEvent::Remove(_)
-                    | DebouncedEvent::Rename(_, _) => {
-                        if builder::build(&watcher_conf).is_ok() {
-                            // change the websocket reload state to true;
-                            // the page will auto-reload.
-                            if watcher_conf
-                                .dioxus_config
-                                .web
-                                .watcher
-                                .reload_html
-                                .unwrap_or(false)
-                            {
-                                let _ = Serve::regen_dev_page(&watcher_conf);
-                            }
-                            println!("send reload!");
-                            watcher_ws_state.send("reload".into()).unwrap();
+        while let Ok(v) = watcher_rx.recv() {
+            match v {
+                DebouncedEvent::Create(_)
+                | DebouncedEvent::Write(_)
+                | DebouncedEvent::Remove(_)
+                | DebouncedEvent::Rename(_, _) => {
+                    if builder::build(&watcher_conf).is_ok() {
+                        // change the websocket reload state to true;
+                        // the page will auto-reload.
+                        if watcher_conf
+                            .dioxus_config
+                            .web
+                            .watcher
+                            .reload_html
+                            .unwrap_or(false)
+                        {
+                            let _ = Serve::regen_dev_page(&watcher_conf);
                         }
+                        reload_tx.send("reload".into()).unwrap();
                     }
-                    _ => {}
                 }
+                _ => {}
             }
         }
     });
 
-    let app = Router::new()
-        .route("/_dioxus/ws", get(ws_handler))
-        .fallback(
-            get_service(ServeDir::new(config.crate_dir.join(&dist_path))).handle_error(
-                |error: std::io::Error| async move {
-                    (
-                        StatusCode::INTERNAL_SERVER_ERROR,
-                        format!("Unhandled internal error: {}", error),
-                    )
-                },
-            ),
-        )
-        .layer(AddExtensionLayer::new(ws_reload_state.clone()));
-
     // start serve dev-server at 0.0.0.0:8080
     let port = "8080";
     log::info!("📡 Dev-Server is started at: http://127.0.0.1:{}/", port);
+
     axum::Server::bind(&format!("0.0.0.0:{}", port).parse().unwrap())
-        .serve(app.into_make_service())
+        .serve(
+            Router::new()
+                .route("/_dioxus/ws", get(ws_handler))
+                .fallback(
+                    get_service(ServeDir::new(config.crate_dir.join(&dist_path))).handle_error(
+                        |error: std::io::Error| async move {
+                            (
+                                StatusCode::INTERNAL_SERVER_ERROR,
+                                format!("Unhandled internal error: {}", error),
+                            )
+                        },
+                    ),
+                )
+                .layer(AddExtensionLayer::new(ws_reload_state))
+                .into_make_service(),
+        )
         .await?;
+
     Ok(())
 }
 
@@ -109,23 +113,24 @@ async fn ws_handler(
     Extension(state): Extension<Arc<WsRelodState>>,
 ) -> impl IntoResponse {
     ws.on_upgrade(|mut socket| async move {
+
+        log::info!("New websocket conenct.");
+
         let mut rx = state.update.subscribe();
+
         loop {
-            println!("wait");
-            if let Ok(v) = rx.recv().await {
-                println!("trigger recv: {}", v);
-                if v == "reload" {
-                    // ignore the error
-                    if socket
-                        .send(Message::Text(String::from("reload")))
-                        .await
-                        .is_err()
-                    {
-                        return;
-                    }
+            let v = rx.recv().await.unwrap();
+            println!("trigger recv: {}", v);
+            if v == "reload" {
+                // ignore the error
+                if socket
+                    .send(Message::Text(String::from("reload")))
+                    .await
+                    .is_err()
+                {
+                    println!("send failed");
+                    return;
                 }
-            } else {
-                println!("SS");
             }
         }
     })