1use wasm_bindgen::prelude::*;
2use wasm_bindgen::JsCast;
3use web_sys::{MessageEvent, WebSocket};
4
5pub struct WsClient {
6 pub ws: WebSocket,
7}
8
9impl WsClient {
10 pub fn new(url: &str) -> Result<Self, JsValue> {
11 let ws = WebSocket::new(url)?;
12 Ok(Self { ws })
13 }
14
15 pub fn on_message<F>(&self, mut callback: F)
16 where
17 F: FnMut(String) + 'static,
18 {
19 let closure = Closure::wrap(Box::new(move |e: MessageEvent| {
20 if let Ok(txt) = e.data().dyn_into::<js_sys::JsString>() {
21 let s = String::from(txt);
22 callback(s);
23 let _ = crate::tick();
24 }
25 }) as Box<dyn FnMut(MessageEvent)>);
26 self.ws.set_onmessage(Some(closure.as_ref().unchecked_ref()));
27 closure.forget();
28 }
29
30 pub fn send(&self, msg: &str) -> Result<(), JsValue> {
31 self.ws.send_with_str(msg)
32 }
33}