branch: main
ws.rs
2385 bytesRaw
use super::SomeSharedData;
use futures_util::StreamExt;
use worker::{
wasm_bindgen_futures, Env, Request, Response, Result, WebSocket, WebSocketPair, WebsocketEvent,
};
pub async fn handle_websocket(_req: Request, env: Env, _data: SomeSharedData) -> Result<Response> {
// Accept / handle a websocket connection
let pair = WebSocketPair::new()?;
let server = pair.server;
server.accept()?;
let some_namespace_kv = env.kv("SOME_NAMESPACE")?;
wasm_bindgen_futures::spawn_local(async move {
let mut event_stream = server.events().expect("could not open stream");
while let Some(event) = event_stream.next().await {
match event.expect("received error in websocket") {
WebsocketEvent::Message(msg) => {
if let Some(text) = msg.text() {
server.send_with_str(text).expect("could not relay text");
}
}
WebsocketEvent::Close(_) => {
// Sets a key in a test KV so the integration tests can query if we
// actually got the close event. We can't use the shared dat a for this
// because miniflare resets that every request.
some_namespace_kv
.put("got-close-event", "true")
.unwrap()
.execute()
.await
.unwrap();
}
}
}
});
Response::from_websocket(pair.client)
}
#[worker::send]
pub async fn handle_websocket_client(
_req: Request,
_env: Env,
_data: SomeSharedData,
) -> Result<Response> {
let ws = WebSocket::connect("wss://echo.miniflare.mocks/".parse()?).await?;
// It's important that we call this before we send our first message, otherwise we will
// not have any event listeners on the socket to receive the echoed message.
let mut event_stream = ws.events()?;
ws.accept()?;
ws.send_with_str("Hello, world!")?;
while let Some(event) = event_stream.next().await {
let event = event?;
if let WebsocketEvent::Message(msg) = event {
if let Some(text) = msg.text() {
return Response::ok(text);
}
}
}
Response::error("never got a message echoed back :(", 500)
}