diff --git a/docs/websockets.md b/docs/websockets.md
index f70368e..fd9de89 100644
--- a/docs/websockets.md
+++ b/docs/websockets.md
@@ -1,22 +1,22 @@
---
-title: Websockets
+title: WebSockets
---
import CodeBlock from "@site/src/components/code_block";
-# Websockets
+# WebSockets
-Actix Web supports WebSockets with the `actix-web-actors` crate. It is possible to convert a request's `Payload` to a stream of [_ws::Message_][message] with a [_web::Payload_][payload] and then use stream combinators to handle actual messages, but it is simpler to handle websocket communications with an http actor.
+Actix Web supports a high-level WebSocket interface via the `actix-ws` crate. Using this crate, it's possible to convert a request's `Payload` stream into a stream of [_ws::Message_][message]s and then react to them inside a spawned async task.
-The following is an example of a simple websocket echo server:
+The following is an example of a simple WebSocket echo server:
-> A simple websocket echo server example is available in the [examples directory][examples].
+> A simple WebSocket echo server example is available [in the examples repo][echo].
-> An example chat server with the ability to chat over a websocket or TCP connection is available in [websocket-chat directory][chat]
+> An example chat server is also available [in the examples directory][chat]
-[message]: https://docs.rs/actix-web-actors/2/actix_web_actors/ws/enum.Message.html
+[message]: https://docs.rs/actix-ws/0.3/actix_ws/enum.Message.html
[payload]: https://docs.rs/actix-web/4/actix_web/web/struct.Payload.html
-[examples]: https://github.com/actix/examples/tree/master/websockets
-[chat]: https://github.com/actix/examples/tree/master/websockets/chat
+[echo]: https://github.com/actix/examples/tree/master/websockets/echo-actorless
+[chat]: https://github.com/actix/examples/tree/master/websockets/chat-actorless
diff --git a/examples/Cargo.lock b/examples/Cargo.lock
index bf39ddb..73a2b79 100644
--- a/examples/Cargo.lock
+++ b/examples/Cargo.lock
@@ -2,31 +2,6 @@
# It is not intended for manual editing.
version = 3
-[[package]]
-name = "actix"
-version = "0.13.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b"
-dependencies = [
- "actix-macros",
- "actix-rt",
- "actix_derive",
- "bitflags 2.5.0",
- "bytes",
- "crossbeam-channel",
- "futures-core",
- "futures-sink",
- "futures-task",
- "futures-util",
- "log",
- "once_cell",
- "parking_lot",
- "pin-project-lite",
- "smallvec",
- "tokio",
- "tokio-util",
-]
-
[[package]]
name = "actix-codec"
version = "0.5.2"
@@ -260,24 +235,6 @@ dependencies = [
"url",
]
-[[package]]
-name = "actix-web-actors"
-version = "4.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "420b001bb709d8510c3e2659dae046e54509ff9528018d09c78381e765a1f9fa"
-dependencies = [
- "actix",
- "actix-codec",
- "actix-http",
- "actix-web",
- "bytes",
- "bytestring",
- "futures-core",
- "pin-project-lite",
- "tokio",
- "tokio-util",
-]
-
[[package]]
name = "actix-web-codegen"
version = "4.3.0"
@@ -291,14 +248,17 @@ dependencies = [
]
[[package]]
-name = "actix_derive"
-version = "0.6.1"
+name = "actix-ws"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3"
+checksum = "a3a1fb4f9f2794b0aadaf2ba5f14a6f034c7e86957b458c506a8cb75953f2d99"
dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.66",
+ "actix-codec",
+ "actix-http",
+ "actix-web",
+ "bytestring",
+ "futures-core",
+ "tokio",
]
[[package]]
@@ -3344,9 +3304,9 @@ dependencies = [
name = "websockets"
version = "1.0.0"
dependencies = [
- "actix",
"actix-web",
- "actix-web-actors",
+ "actix-ws",
+ "futures-util",
]
[[package]]
diff --git a/examples/websockets/Cargo.toml b/examples/websockets/Cargo.toml
index b6d88fa..82200f4 100644
--- a/examples/websockets/Cargo.toml
+++ b/examples/websockets/Cargo.toml
@@ -5,6 +5,6 @@ publish = false
edition.workspace = true
[dependencies]
-actix = "0.13"
actix-web = "4"
-actix-web-actors = "4.0.0"
+actix-ws = "0.3"
+futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
diff --git a/examples/websockets/src/main.rs b/examples/websockets/src/main.rs
index 8a0bff9..228682c 100644
--- a/examples/websockets/src/main.rs
+++ b/examples/websockets/src/main.rs
@@ -1,36 +1,48 @@
//
-use actix::{Actor, StreamHandler};
-use actix_web::{web, App, Error, HttpRequest, HttpResponse, HttpServer};
-use actix_web_actors::ws;
+use actix_web::{rt, web, App, Error, HttpRequest, HttpResponse, HttpServer};
+use actix_ws::AggregatedMessage;
+use futures_util::StreamExt as _;
-/// Define HTTP actor
-struct MyWs;
+async fn echo(req: HttpRequest, stream: web::Payload) -> Result {
+ let (res, mut session, stream) = actix_ws::handle(&req, stream)?;
-impl Actor for MyWs {
- type Context = ws::WebsocketContext;
-}
+ let mut stream = stream
+ .aggregate_continuations()
+ // aggregate continuation frames up to 1MiB
+ .max_continuation_size(2_usize.pow(20));
-/// Handler for ws::Message message
-impl StreamHandler> for MyWs {
- fn handle(&mut self, msg: Result, ctx: &mut Self::Context) {
- match msg {
- Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
- Ok(ws::Message::Text(text)) => ctx.text(text),
- Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
- _ => (),
+ // start task but don't wait for it
+ rt::spawn(async move {
+ // receive messages from websocket
+ while let Some(msg) = stream.next().await {
+ match msg {
+ Ok(AggregatedMessage::Text(text)) => {
+ // echo text message
+ session.text(text).await.unwrap();
+ }
+
+ Ok(AggregatedMessage::Binary(bin)) => {
+ // echo binary message
+ session.binary(bin).await.unwrap();
+ }
+
+ Ok(AggregatedMessage::Ping(msg)) => {
+ // respond to PING frame with PONG frame
+ session.pong(&msg).await.unwrap();
+ }
+
+ _ => {}
+ }
}
- }
-}
+ });
-async fn index(req: HttpRequest, stream: web::Payload) -> Result {
- let resp = ws::start(MyWs {}, &req, stream);
- println!("{:?}", resp);
- resp
+ // respond immediately with response connected to WS session
+ Ok(res)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
- HttpServer::new(|| App::new().route("/ws/", web::get().to(index)))
+ HttpServer::new(|| App::new().route("/echo", web::get().to(echo)))
.bind(("127.0.0.1", 8080))?
.run()
.await