Fix websocket server functions and add an example (#4107)

* Fix websocket server function

* Add websocket test

* add a websocket example

* fix clippy
This commit is contained in:
Evan Almloff authored and GitHub committed 2025-05-14 08:28:43 +02:00
1 parent e47d0aa868
commit 6b70ba7cd2
10 files changed
+297 -12

No files matched your search

@@ -68,3 +68,11 @@ test("document elements", async ({ page }) => {
const main = page.locator("#main");
await expect(main).toHaveCSS("font-family", "Roboto");
});
test("websockets", async ({ page }) => {
await page.goto("http://localhost:3333");
// wait until the websocket div is mounted
const wsDiv = page.locator("div#websocket-div");
await expect(wsDiv).toHaveText("Received: HELLO WORLD");
});
@@ -8,6 +8,7 @@ publish = false
[dependencies]
dioxus = { workspace = true, features = ["fullstack"] }
futures.workspace = true
serde = "1.0.218"
tokio = { workspace = true, features = ["full"], optional = true }
@@ -5,7 +5,14 @@
// - Hydration
#![allow(non_snake_case)]
use dioxus::{prelude::*, CapturedError};
use dioxus::{
prelude::{
server_fn::{codec::JsonEncoding, BoxedStream, Websocket},
*,
},
CapturedError,
};
use futures::{channel::mpsc, SinkExt, StreamExt};
fn main() {
dioxus::LaunchBuilder::new()
@@ -43,6 +50,7 @@ fn app() -> Element {
OnMounted {}
DefaultServerFnCodec {}
DocumentElements {}
WebSockets {}
}
}
@@ -156,3 +164,42 @@ fn DocumentElements() -> Element {
document::Style { id: "style-head", "body {{ font-family: 'Roboto'; }}" }
}
}
#[server(protocol = Websocket<JsonEncoding, JsonEncoding>)]
async fn echo_ws(
input: BoxedStream<String, ServerFnError>,
) -> Result<BoxedStream<String, ServerFnError>, ServerFnError> {
let mut input = input;
let (mut tx, rx) = mpsc::channel(1);
tokio::spawn(async move {
while let Some(msg) = input.next().await {
let _ = tx.send(msg.map(|msg| msg.to_ascii_uppercase())).await;
}
});
Ok(rx.into())
}
/// This component tests websocket server functions
#[component]
fn WebSockets() -> Element {
let mut received = use_signal(String::new);
use_future(move || async move {
let (mut tx, rx) = mpsc::channel(1);
let mut receiver = echo_ws(rx.into()).await.unwrap();
tx.send(Ok("hello world".to_string())).await.unwrap();
while let Some(Ok(msg)) = receiver.next().await {
println!("Received: {}", msg);
received.set(msg);
}
});
rsx! {
div {
id: "websocket-div",
"Received: {received}"
}
}
}