Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗rsSpWsCs 275 of 288 menu
◀ ▶

Закрытие WebSocket в Rust

Сторона может штатно завершить канал кадром закрытия. Сервер перестает читать, когда видит этот вариант или когда чтение возвращает пустой результат после разрыва.

На сервере выходим из цикла при варианте закрытия:

use axum::{ extract::ws::{Message, WebSocket, WebSocketUpgrade}, response::IntoResponse, routing::get, Router, }; #[tokio::main] async fn main() { let app = Router::new().route("/", get(ws_entry)); let listener = match tokio::net::TcpListener::bind("127.0.0.1:3000").await { Ok(l) => l, Err(e) => { eprintln!("{}", e); return; } }; match axum::serve(listener, app).await { Ok(()) => {} Err(e) => eprintln!("{}", e), } } async fn ws_entry(ws: WebSocketUpgrade) -> impl IntoResponse { ws.on_upgrade(handle_socket) } async fn handle_socket(mut socket: WebSocket) { loop { let msg = match socket.recv().await { Ok(Some(m)) => m, Ok(None) => break, Err(e) => { eprintln!("{}", e); break; } }; match msg { Message::Text(text) => println!("{}", text), Message::Close(_) => { println!("bye"); break; } _ => {} } } println!("loop end"); }

После выхода из цикла можно освободить ресурсы и перестать слать кадры в этот сокет. Пустой результат чтения тоже ведет к строке loop end без отдельного кадра.

Клиент может отправить кадр закрытия перед выходом из программы:

use futures_util::{SinkExt, StreamExt}; use tokio_tungstenite::{connect_async, tungstenite::Message}; #[tokio::main] async fn main() { let url = "ws://127.0.0.1:3000"; let (stream, _response) = match connect_async(url).await { Ok(pair) => pair, Err(e) => { eprintln!("{}", e); return; } }; let (mut write, _read) = stream.split(); match write.send(Message::Close(None)).await { Ok(()) => println!("sent close"), Err(e) => eprintln!("{}", e), } }

Дан текст перед закрытием:

let text = "done";

На клиенте отправьте этот текст, затем кадр закрытия и выведите exit после успешной записи закрытия.

Закрытие:

match msg { Message::Close(_) => break, Message::Text(text) => println!("{}", text), _ => {} }

Вставьте фрагмент в цикл чтения сервера и скажите, что произойдет, если клиент оборвет сеть без кадра закрытия.

Скажите, почему после break из цикла чтения не стоит снова писать в тот же сокет.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить