Skip to content

websocket disconnect error handler not implemented #499

Open
@qknight

Description

@qknight

Bug Report

The client side code below, running in google chrome, will never call the Err(e) condition of write.send when the WS is disconnected from the webserver.

log::info!("Sent ping"); will appear with a error message i think originates from the webbrowser's websocket implementation:

Image

Version

  • cargo 1.85.0 (d73d2caf9 2024-12-31)
  • wasm-pack --version wasm-pack 0.13.1
  • chrome Version 133.0.6943.127 (Offizieller Build) (64-Bit)

Platform

wasm32-unknown-unknown

build with:

wasm-pack build --target web --release

It requires a webserver websocket which it can connect to. I'm using axum 0.7.9 on the server, see:

Crates

[package]
name = "pankat-wasm"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = "1.0"
reqwest = { version = "0.11", features = ["json"] }
web-sys = { version = "0.3", features = ["WebSocket", "console", "MessageEvent", "Window", "Location", "Element", "DomTokenList", "CssStyleDeclaration"] } 
wasm-bindgen = "0.2.100"
log = "0.4.25"
futures = "*"
wasm-bindgen-futures = "0.4.50"
console_log = "1.0.0"
gloo-net = { version = "0.5.0", default-features = false, features = ["websocket"] }
gloo-utils = { version = "0.2.0", default-features = false }
gloo-timers = { version = "0.3.0", features = ["futures"] }
anyhow = "1.0.95"

[lib]
crate-type = ["cdylib", "rlib"]

Description

     1  use futures::StreamExt;
     2  use gloo_net::websocket::{futures::WebSocket, Message};
     3  use gloo_utils::window;
     4  use std::{cell::RefCell, rc::Rc};
     5  use wasm_bindgen::prelude::*;
     6  use wasm_bindgen_futures::spawn_local;
     7  use web_sys::{Element, HtmlElement};
     8
     9  #[wasm_bindgen(start)]
    10  pub fn main_js() -> Result<(), JsValue> {
    11      console_log::init_with_level(log::Level::Info).expect("error initializing log");
    12      log::info!("Now executing WASM code from lib.rs in pankat_wasm");
    13
    14      spawn_local({
    15          async move {
    16              loop {
    17                  let location = window().location();
    18                  let protocol = if location.protocol().unwrap() == "https:" {
    19                      "wss"
    20                  } else {
    21                      "ws"
    22                  };
    23
    24                  let host = location.host().unwrap();
    25                  let websocket_address = format!("{protocol}://{host}/api/ws");
    26
    27                  match WebSocket::open(&websocket_address) {
    28                      Ok(ws) => {
    29                          let (mut write, mut read) = ws.split();
    30                          use futures::SinkExt;
    31                          spawn_local(async move {
    32                              loop {
    33                                  gloo_timers::future::sleep(std::time::Duration::from_secs(1)).await;
    34                                  match write.send(Message::Text("ping".to_string())).await {
    35                                      Ok(_) => {
    36                                          log::info!("Sent ping");
    37                                      }
    38                                      Err(e) => {
    39                                          // BUG code never reached when WS goes down
    40                                          log::warn!("Failed to send ping");
    41                                          return;
    42                                      }
    43                                  }
    44                              }
    45                          });
    46                          while let Some(result) = read.next().await {
    47                              match result {
    48                                  Ok(msg) => match msg {
    49                                      Message::Text(message) => match message.as_str() {
    50                                          "pong" => {
    51                                              log::info!("WS: received a pong to our ping, connection is working!");
    52                                          }
    53                                          _ => {
    54                                              log::info!("Received WS message");
    55                                          }
    56                                      },
    57                                      Message::Bytes(_) => {
    58                                          log::warn!("Binary messages are not supported yet");
    59                                      }
    60                                  },
    61                                  Err(e) => {
    62                                      log::warn!("Err0r {e}");
    63                                      return;
    64                                  }
    65                              }
    66                          }
    67                          log::info!(
    68                              "WebSocket disconnected, attempting to reconnect in 1 second..."
    69                          );
    70                      }
    71                      Err(e) => {
    72                          log::error!("Failed to connect: {}", e);
    73                      }
    74                  }
    75                  gloo_timers::future::sleep(std::time::Duration::from_secs(1)).await;
    76              }
    77          }
    78      });
    79
    80      Ok(())
    81  }

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions