MCPcopy Create free account
hub / github.com/actix/examples / chat_ws

Function chat_ws

websockets/chat-actorless/src/handler.rs:17–87  ·  view source on GitHub ↗

Echo text & binary messages received from the client, respond to ping messages, and monitor connection health to detect network issues and free up resources.

(
    chat_server: ChatServerHandle,
    mut session: actix_ws::Session,
    msg_stream: actix_ws::MessageStream,
)

Source from the content-addressed store, hash-verified

15/// Echo text & binary messages received from the client, respond to ping messages, and monitor
16/// connection health to detect network issues and free up resources.
17pub async fn chat_ws(
18 chat_server: ChatServerHandle,
19 mut session: actix_ws::Session,
20 msg_stream: actix_ws::MessageStream,
21) {
22 log::info!("connected");
23
24 let mut name: Option<String> = None;
25 let mut last_heartbeat = Instant::now();
26 let mut interval = interval(HEARTBEAT_INTERVAL);
27
28 let (conn_tx, mut conn_rx) = mpsc::unbounded_channel();
29
30 // unwrap: chat server is not dropped before the HTTP server
31 let conn_id = chat_server.connect(conn_tx).await;
32
33 let mut msg_stream = msg_stream
34 .max_frame_size(128 * 1024)
35 .aggregate_continuations()
36 .max_continuation_size(2 * 1024 * 1024);
37
38 let close_reason = loop {
39 tokio::select! {
40 Some(Ok(msg)) = msg_stream.next() => {
41 log::debug!("msg: {msg:?}");
42
43 match msg {
44 AggregatedMessage::Ping(bytes) => {
45 last_heartbeat = Instant::now();
46 session.pong(&bytes).await.unwrap();
47 }
48
49 AggregatedMessage::Pong(_) => {
50 last_heartbeat = Instant::now();
51 }
52
53 AggregatedMessage::Text(text) => {
54 process_text_msg(&chat_server, &mut session, &text, conn_id, &mut name)
55 .await;
56 }
57
58 AggregatedMessage::Binary(_bin) => {
59 log::warn!("unexpected binary message");
60 }
61
62 AggregatedMessage::Close(reason) => break reason,
63 }
64 }
65
66 Some(chat_msg) = conn_rx.recv() => {
67 session.text(chat_msg).await.unwrap();
68 }
69
70 _ = interval.tick() => {
71 if Instant::now().duration_since(last_heartbeat) > CLIENT_TIMEOUT {
72 break None;
73 }
74 let _ = session.ping(b"").await;

Callers

nothing calls this directly

Calls 2

connectMethod · 0.80
disconnectMethod · 0.80

Tested by

no test coverage detected