aboutsummaryrefslogtreecommitdiffstats
path: root/teleterm-web/src/ws.rs
diff options
context:
space:
mode:
Diffstat (limited to 'teleterm-web/src/ws.rs')
-rw-r--r--teleterm-web/src/ws.rs55
1 files changed, 55 insertions, 0 deletions
diff --git a/teleterm-web/src/ws.rs b/teleterm-web/src/ws.rs
new file mode 100644
index 0000000..a2ab566
--- /dev/null
+++ b/teleterm-web/src/ws.rs
@@ -0,0 +1,55 @@
+use crate::prelude::*;
+use wasm_bindgen::JsCast as _;
+
+pub(crate) fn connect(
+ url: &str,
+ orders: &mut impl Orders<crate::Msg>,
+) -> WebSocket {
+ let ws = WebSocket::new(url).unwrap();
+
+ register_ws_handler(
+ WebSocket::set_onopen,
+ crate::Msg::Connected,
+ &ws,
+ orders,
+ );
+ register_ws_handler(
+ WebSocket::set_onclose,
+ crate::Msg::Disconnected,
+ &ws,
+ orders,
+ );
+ register_ws_handler(
+ WebSocket::set_onmessage,
+ crate::Msg::Message,
+ &ws,
+ orders,
+ );
+ register_ws_handler(
+ WebSocket::set_onerror,
+ crate::Msg::Error,
+ &ws,
+ orders,
+ );
+
+ ws
+}
+
+fn register_ws_handler<T, F>(
+ ws_cb_setter: fn(&WebSocket, Option<&js_sys::Function>),
+ msg: F,
+ ws: &web_sys::WebSocket,
+ orders: &mut impl Orders<crate::Msg>,
+) where
+ T: wasm_bindgen::convert::FromWasmAbi + 'static,
+ F: Fn(T) -> crate::Msg + 'static,
+{
+ let (app, msg_mapper) = (orders.clone_app(), orders.msg_mapper());
+
+ let closure = Closure::new(move |data| {
+ app.update(msg_mapper(msg(data)));
+ });
+
+ ws_cb_setter(ws, Some(closure.as_ref().unchecked_ref()));
+ closure.forget();
+}