Я пытаюсь подключиться к веб-сокету на сервере, к которому сокет выдает ошибку о том, что не удалось подключиться.
Код ржавчины:
use axum::{
extract::{ws::WebSocket, WebSocketUpgrade},
response::IntoResponse,
routing::get,
Router,
};
use tokio::net::TcpListener;
use tower_http::services::ServeDir;
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("localhost:3000").await.unwrap();
axum::serve(listener, router()).await.unwrap();
}
fn router() -> Router {
Router::new()
.route("/message_list", get(hello_world))
.nest_service("/", ServeDir::new("static"))
}
async fn hello_world(ws: WebSocketUpgrade) -> impl IntoResponse {
let _res = ws.on_upgrade(|ws| socet_handler(ws));
}
async fn socet_handler(mut ws: WebSocket) {
println!("IT READY!");
let _res = ws.send(axum::extract::ws::Message::Text("hi".to_string()));
}
js-код:
let socket = new WebSocket("ws://localhost:3000/message_list")
Я также пытался изменить «ws» на «wss» в URL-адресе, но это не помогло. на сайте постоянная ошибка:
Соединение WebSocket с «ws://localhost:3000/message_list» не удалось
С чем это может быть связано?
А) Вы уверены, что служба Rust запущена и принимает соединения? Можете ли вы подтвердить это с помощью другого инструмента, например curl
? Б) Они оба находятся на одной локальной машине? Один из них находится в контейнере, где localhost
находится относительно него?
да, сервис ржавчины запущен и принимает соединения, функция "soket_handler" имеет команду, которая отправляет сообщение при подключении, и она срабатывает корректно при каждом запуске. оба они находятся на одной локальной машине
Ваш socet_handler
не поддерживает соединение с веб-сокетом, он отправляет сообщение, а затем немедленно завершает функцию - удаляя веб-сокет.
Попробуйте добавить цикл прослушивания сообщений, как описано в документации:
async fn socet_handler(mut socket: WebSocket) {
println!("IT READY!");
let _res = ws.send(axum::extract::ws::Message::Text("hi".to_string())).await;
while let Some(msg) = socket.recv().await {
// handle the message
}
}
Ваш код также отбрасывает ответ, созданный из on_upgrade
, и вместо этого возвращает пустой (()
) ответ. Удалите часть let _res =
и дайте ей вернуться следующим образом:
async fn hello_world(ws: WebSocketUpgrade) -> impl IntoResponse {
ws.on_upgrade(|ws| socet_handler(ws))
}
Вы также не .await
совершали send
звонок, а это значит, что он на самом деле не был отправлен.
Вы не сможете использовать
wss://
без слоя TLS.