You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Discusion around using gloo::net::websocket with Dioxuss and reopen a closed connection.
I didn't find any other example, except on the doc, so I thought this might help.
It's certainly not the best way to implement it, I'm still fairly new to Rust and Dioxus.
If the connection goes down, there's no way to reopen a new one, if you have any suggestions on how to implement it, or if you know of a better solution for using websocket with Dioxus, feel free to contribute.
I didn't find a way to call restart(), as it can be done with UseFuture, as stated in the doc.
And, if, upon websocket connection closed, I recreate a UseCoroutine, I will still get the previous one when calling use_coroutine_handle::<_>()
And since I moved rx in an async move {} bloc (cf. section "SEND"), I cannot put the inner coroutine code inside a loop {} bloc.
in order to reopen a WebSocket::open(url) upon connection closed, but a deadlock can happen easily if not handled carefully
Here's the code for the WebSocket example
use dioxus::prelude::*;use futures::{
stream::SplitSink,{SinkExt,StreamExt},};use gloo::net::websocket::{futures::WebSocket,Message,WebSocketError};usecrate::commons::AppState;fnApp(cx:Scope<'_>) -> Element{// AppState is a struct with some fields to store data like websocket server responsesuse_shared_state_provider(cx, || AppState::new());init_websocket_coroutine()let msg_rcv = use_shared_state::<AppState>(cx).unwrap().read().text;let ws = use_coroutine_handle::<Message>(cx).unwrap();render!{
h1 {"Hello world!"}
button {
onclick: |_| ws.send(Message::Text("Hi from client".to_string())),"Say hi to server"}
p {"Last text message received from server: {msg_rcv}"}}}/// Spawn a coroutine with a websocket connectionfninit_websocket_coroutine(url:&str){// shared state so websocket messages can be saved when receivedlet app_state = use_shared_state::<AppState>(cx).unwrap();// websocket coroutine// <Message> can be replaced by any custom enum to provide more control, // but in the end write() only takes gloo::net::websocket::Message enum variantlet ws = use_coroutine(cx, |mutrx:UnboundedReceiver<Message>| {to_owned![app_state];asyncmove{let ws = WebSocket::open(url).unwrap();let(mut write,mut read) = ws.split();// SEND messages to server with ws.send(CustomEnum::_)spawn_local(asyncmove{whileletSome(msg) = rx.next().await{// you can match msg - to better control what you send - if you replace the current // |mut rx: UnboundedReceiver<Message>| with // |mut rx: UnboundedReceiver<CustomEnum>|// but here I dont need to match it since it is gloo::net::websocket::Message// and write() take a Message enum variant as argumentmatch write.send(msg).await{Ok(_) => log::info!("[WebSocket] Message sent to server"),Err(ws_err) => log::error!("[WebSocket] Error sending to server -> {ws_err}"),};}});// READ incoming messagesspawn_local(asyncmove{whileletSome(recv_msg) = read.next().await{// match type of received message: Result<Message, WebSocketError>// after matching the type you can use match with serde_json if you serialized different objects// however, here, I stop at storing the message into my shared_state structmatch recv_msg {// stringOk(Message::Text(text)) => app_state.write().text = text.clone(),// bytesOk(Message::Bytes(bytes)) => app_state.write().bytes = bytes.clone(),// clean connection closeErr(WebSocketError::ConnectionClose(close_event))if close_event.was_clean =>
log::info!("[WebSocket] ConnectionClose: {:#?}", close_event),// any other errorErr(ws_err) => log::error!("[WebSocketError]: {:#?}", ws_err),}}});}});}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Discusion around using
gloo::net::websocket
withDioxuss
and reopen a closed connection.I didn't find any other example, except on the doc, so I thought this might help.
It's certainly not the best way to implement it, I'm still fairly new to Rust and Dioxus.
If the connection goes down, there's no way to reopen a new one, if you have any suggestions on how to implement it, or if you know of a better solution for using websocket with Dioxus, feel free to contribute.
Here's the code for the WebSocket example
Beta Was this translation helpful? Give feedback.
All reactions