use wasm_bindgen::prelude::*; use wasm_bindgen::JsCast; use web_sys::{ErrorEvent, MessageEvent, WebSocket}; macro_rules! console_log { ($($t:tt)*) => (log(&format_args!($($t)*).to_string())) } #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } #[wasm_bindgen(start)] pub fn start_websocket() -> Result<(), JsValue> { // Connect to an echo server let ws = WebSocket::new("wss://echo.websocket.org")?; // create callback let onmessage_callback = Closure::wrap(Box::new(move |e: MessageEvent| { // handle message let response = e .data() .as_string() .expect("Can't convert received data to a string"); console_log!("message event, received data: {:?}", response); }) as Box); // set message event handler on WebSocket ws.set_onmessage(Some(onmessage_callback.as_ref().unchecked_ref())); // forget the callback to keep it alive onmessage_callback.forget(); let onerror_callback = Closure::wrap(Box::new(move |e: ErrorEvent| { console_log!("error event: {:?}", e); }) as Box); ws.set_onerror(Some(onerror_callback.as_ref().unchecked_ref())); onerror_callback.forget(); let cloned_ws = ws.clone(); let onopen_callback = Closure::wrap(Box::new(move |_| { console_log!("socket opened"); match cloned_ws.send_with_str("ping") { Ok(_) => console_log!("message successfully sent"), Err(err) => console_log!("error sending message: {:?}", err), } }) as Box); ws.set_onopen(Some(onopen_callback.as_ref().unchecked_ref())); onopen_callback.forget(); Ok(()) }