Веб-фреймворк Rust, который вы должны знать
Веб-фреймворк Rust, который вы должны знать

❝Верьте в силу веры ❞

Всем привет,яда«Семь, восемь, девять»

Предисловие

существовать Доизиспользовать Rust строить React Server Components из Web серверяихвыгодаиспользовать ПонятноAxumстроить ПонятноRSCизсервер。Также расчетдаиспользоватьRustсуществоватьстроитьWebСлужитьначальствоиз Проверьте свои навыки。

ХотяAxumсуществоватьRust Webотвечатьиспользовать Выдающийся среди всех。нода,рынокначальство Также есть много различийизрешение。так,сегодняяих就比较一些 Rust рамка,Выделите их соответствующие преимущества и недостатки.,помочьяихдля Проект стал мудрымизпринятие решений。Без сравнения нет выбора.,Нам остается только по-настоящему понять преимущества и недостатки каждой кадры и адаптироваться к сцене.,существовать Только в будущем развитии мы сможем иметь безопасный выбор.

в тексте,яих会介绍很多Rustрамка。и будет следующимизпопулярностьиз В плане порядка。

Ладно, уже поздно, давайте приступим к делу.

Чему мы можем научиться

  1. Axum
  2. Actix Web
  3. Rocket
  4. Warp
  5. Tide
  6. Poem


1. Axum

Axum[1] да Rust Имеет особый статус в экосистеме Web Прикладная программа в рамке (это видно по количеству скачиваний). это да Tokio проект[2]изчасть,Tokio даделатьиспользовать Rust писать«Асинхронное сетевое приложение использует программу во время выполнения»Axum не только использовать Tokio Поскольку его асинхронная среда выполнения также работает с Tokio Экосистема из Интеграция других библиотек, выгода от использования Hyper[3] как это HTTP сервер и Tower[4] в качестве промежуточного программного обеспечения. Делая это, мы можем повторно использовать Tokio В экосистеме существуют существующие библиотеки и инструменты.

Axum «Не зависит от макросов»,идавыгодаиспользовать Rust изсистема типовОбеспечить безопасность и удобство использованияиз API. Это определяет реализацию базовой абстракции кадра путем создания атрибута use, например Handler характеристика,использовать В«Определение должно использовать исходную логику программы»。этотдобрыйметодпозволятьяих轻松地「отменьшеизкомпонентысерединакомбинацияотвечатьиспользоватьпрограмма」,Эти компоненты можно использовать в нескольких приложениях.

существовать Axum середина,иметь дело спрограмма(handler)даодин«Принять запрос и вернуть ответ»изфункция。этоти Другие бэкэндырамкапохожий,ноделатьиспользовать Axum из FromRequest Свойства, мы можем указать тип данных, которые будут извлечены из запроса. Тип возвращаемого значения должен быть реализован. IntoResponse характеристика(trait),Уже существует множество типов, реализующих эту функцию.,Включает тип кортежа, который позволяет легко изменять ответ по коду состояния и типу кортежа.

Rust изсистема типов、Дженерики,особеннодасуществоватьtraitsсерединаделатьиспользоватьасинхронный метод(или Более конкретнодавозвращатьсяиз Future),когда не удовлетворенtraitКогда ограничено,Rust из Сообщения об ошибках могут быть сложными。особенныйда При попытке сопоставить абстрактноеtraitКогда ограничено,Часто вы получаете кучу трудно интерпретируемыхизтекст。дляэтотAxum поставлять Понятноодин С вспомогательным Макросиз Библиотека,ВоляError размещается там, где действительно произошла ошибка.,Облегчает понимание того, что пошло не так.

ХотяAxum Делать Понятномного правизиметь значение,может легкозапускатьвыполнять множество задачизотвечатьиспользоватьпрограмма。нода,Есть некоторыеиметь значениенуждатьсяособенный Уведомление。AxumВерсиявсе еще низкий В 1.0,Это означаетAxum Команда зарезервированасуществоватьмежду версиями«Принципиально изменить API избесплатно」,Это может вызвать серьезные проблемы с нашим приложением.


Пример Аксума

Ниже показан WebSocket иметь дело спрограмма,Он будет повторять любое полученное сообщение.

Язык кода:javascript
копировать
// #[tokio::main] Макрос с тегами `main` Функция, указывающая, что эта асинхронная программа из `Tokio` должна использовать программу.
#[tokio::main]
async fn main() {
    // Впервые создан один `TcpListener` Слушатель, привязанный к адресу "127.0.0.1:3000" начальство
    // Затем пройдите `await` Дождитесь завершения привязки прослушивателя
    // Если привязка не удалась, она пройдет `unwrap` Метод выдает ошибку.
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
        .await
        .unwrap();
    println!("listening on {}", listener.local_addr().unwrap());
    // делатьиспользовать `axum::serve` запускать Axum рамкаизсервер,
    //    Послушать предыдущее творение из `TcpListener`。
    // `app()` функциявозвращатьсяиздаодин `Router`
    //    Он определяет простой одиниз маршрут, который преобразует путь "/a" Карта для обработки функции `a_handler`。
    axum::serve(listener, app()).await.unwrap();
}

// Возврат один `Маршрутизатор`, который имеет только одно правило маршрутизации,
//    Воля "/a" путь, сопоставленный с `a_handler` иметь дело сфункция
fn app() -> Router {
    Router::new()
        .route("/a", get(a_handler))
}

// Один обработчик WebSocket, который будет отображать любое полученное сообщение.
// Определен как один обработчик WebSocket,
//   он получает один `WebSocketUpgrade` Параметр, указывающий обновление WebSocket.
async fn a_handler(ws: WebSocketUpgrade) -> Response {
    // настраиватьиспользовать ВоляWebSocketПосле обновленияизобъектперешел к `a_handle_socket` иметь дело сфункция。
    ws.on_upgrade(a_handle_socket)
}

async fn a_handle_socket(mut socket: WebSocket) {
    // делатьиспользовать while let цикл, продолжающийся с WebSocket Получайте сообщения в соединении. 
    // socket.recv().await Принимать сообщения асинхронно,Возврат один Result,
    // в Ok(msg) Указывает, что сообщение было успешно получено.
    while let Some(Ok(msg)) = socket.recv().await {
        //  делатьиспользовать if let Сопоставьте и определите, является ли полученное сообщение да текстовым сообщением.
        //  Сообщения WebSocket могут быть разных типов, здесь мы имеем дело только с текстовыми сообщениями.
        if let Message::Text(msg) = msg {
            // структураодинэхо-сообщение,Воляклиентотправлятьизсообщение содержитсуществоватьэхо-сообщениесередина。
            // Затем,делатьиспользовать socket.send метод Воляэхо-сообщениеотправлятьразклиент。
            // await Дождитесь завершения операции отправки.
            if socket
                .send(Message::Text(format!("You said: {msg}")))
                .await
                // исследовать send Операция да Нет возвращает ошибку.
                // Если при отправке сообщения произошла ошибка (например, соединение отключено),
                // Просто пройди break Выйдите из цикла и завершите функцию обработки.
                .is_err()
            {
                break;
            }
        }
    }
}

Функции

  • Нет макроса API.
  • выгодаиспользовать TokioTower и Hyper Создайте мощную экосистему.
  • Отличный опыт разработки.
  • все еще в 0.x версию и поэтому может претерпевать существенные изменения.

2. Actix Web

Actix Web[5] да Rust Существование Zhongde существует уже давно и пользуется большой популярностью. Web рамка№1。как любой хорошийиз Открытый исходный кодпроект Такой же,оно прошло через множество итераций,ноужедостигли Понятноосновная версия(больше никогдада 0.x),другими словами:существоватьосновная версияВнутри,Это гарантирует отсутствие деструктивных изменений.

на первый взгляд,Actix Web и Rust серединаиз Другие Web рамкаочень похоже。яихделатьиспользоватьМакросопределить HTTP-методимаршрутизация(похожий В Rocket),иделатьиспользоватьэкстрактор(extractors)отпроситьсередина Получить данные(похожий В Axum)。и Axum по сравнению с,Между ними есть значительное сходство,дажесуществоватьони называют понятияихарактеристикаиз Способначальствотоже очень похоже。максимумизразницада Actix Web Нет Воля СобственныйиTokio Экосистемы прочно связаны и существуют вместе. Хотя Tokio Все еще да Actix Web Базовая среда выполнения имеет свои собственные абстрактные функции, а также собственный набор crates экосистема. В этом есть как плюсы, так и минусы. С одной стороны, мы можем убедиться, что все работает хорошо, с другой стороны, мы можем упустить Tokio Многие функции уже доступны в экосистеме.

Actix Web Реализовать себя из Service характеристика,это основнойначальствои Tower из Service То же самое, но все еще несовместимо. Это значит существовать Tower Большая часть доступного промежуточного программного обеспечения в экосистеме существует. Actix Недоступно в .

еслисуществовать Actix Web Некоторые специальные задачи необходимо реализовать в , и нам нужно реализовать их самостоятельно. Мы можем столкнуться с запуском кадрасерединаiz. Actor Модель. Это может вызвать некоторые непредвиденные проблемы.

но Actix Web Сообщество отличное. Фреймворк поддерживает HTTP/2 и WebSocket модернизация, предусматривает Web Самые распространенные задачи в кадризе crates и Руководство,и отличная документация,ии очень быстро。Actix Web Изтакпопулярный,да, есть причина,«Если нам нужно гарантировать версию,Обратите внимание, что на данный момент это может быть нашим лучшим вариантом.


Веб-пример Actix

существовать Actix Web Средний, один простойиз WebSocket Эхо-сервер выглядит так:

Язык кода:javascript
копировать
use actix::{Actor, StreamHandler};
use actix_web::{
  web, 
  App, 
  Error, 
  HttpRequest, 
  HttpResponse, 
  HttpServer
};
use actix_web_actors::ws;

/// Определить HTTP Actor
// один определяется как MyWs из структуры,этот ВоляиспользоватьделатьWebSocketизActix Actor。
// Actors да Actixрамка из модуля параллелизма, использовать для обработки асинхронных сообщений
struct MyWs;

// для MyWs Структура реализована Actor черта, указанная WebsocketContext делатьдляначальствотип контекста。
impl Actor for MyWs {
    type Context = ws::WebsocketContext<Self>;
}

/// Обработка сообщения ws::Message из обработчика
// для MyWs Структура реализована StreamHandler черта, обрабатывает сообщения в WebSocketсоединять.
impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWs {
    // Обработку полученных сообщений разного типа руководить. Например, для Ping сообщение, отправить Pong информацияделатьдлякольцоотвечать。
    fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, 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),
            _ => (),
        }
    }
}

// один определен для асинхронной обработки HTTP-запросов.
async fn index(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
    // ВоляWebSocketсоединятьобновление,И Воляпросить поручено MyWs Actor иметь дело с.
    let resp = ws::start(MyWs {}, &req, stream);
    println!("{:?}", resp);
    resp
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    //  Создано один HttpServer например, через App::new() Создать одинотвечатьиспользовать,// Здесь следует использовать только один маршрут,Воляпуть "/ws/" Карта для обработки функции index начальство。
    HttpServer::new(|| App::new().route("/ws/", web::get().to(index)))
        // Привязать сервер к адресу "127.0.0.1" и порт 8080。
        .bind(("127.0.0.1", 8080))?
        // запускатьсервери Подождите, пока он завершит работу。
        .run()
        .await
}

Веб-функции Actix

  • Имеет сильную экосистему.
  • на основе Actor Модель.
  • проходитьосновная версия Гарантирована стабильность API。
  • Отличная документация.

3. Rocket

Rocket[6] существовать Rust Web Уже некоторое время находится в экосистеме рамок: это основные функции основеМакросизмаршрутизацияВстроенные формыиметь дело с、к данным Библиотекаи Управление статусамиизподдерживать,и его Собственный Версияизшаблон!Rocket Делайте все возможное, чтобы построить один Web Все необходимое для программы должно быть включено.

Однако,Rocket Амбиции также сопряжены с некоторыми издержками. Несмотря на то, что он все еще находится в активной разработке, выпуски выходят не так часто, как раньше. Это значит, что пользователи «рамазиспользовать» упустят много важного.

также,Благодаря комплексному подходу,яихвозвращатьсянуждаться Понятноразвязать Rocket извыполнить Способ。Rocket отвечатьиспользоватьпрограммаиметьодин"жизненный цикл",Строительные блоки особым образом,если что-то пойдет не так,Нам нужно понять, в чем заключается проблема.

Rocket даодин — отличная израмка, если мы хотим начать использовать Rust руководить Web развивать,этодаодиночень хорошийизвыбирать。«Для многих из нас,Rocket даэнтер Rust«Первый шаг»,Пусть это будет по-прежнему весело.

Пример ракеты

иметь дело сформаиз Rocket Процедуру следует упростить:

Язык кода:javascript
копировать
// один определяется как Password из структуры, которая выводит Debug и FromForm traits。
// FromForm trait use используется для извлечения данных из данных формы.
// Эта структура содержит два поля first и второй соответственно представляет собой вторую часть пароля из одини.
#[derive(Debug, FromForm)]
struct Password<'v> {
    // Представляет пару полейиздлинаруководить Понятнопроверять,Требоватьдлинасуществовать6символы, начинающиеся сначальство
    #[field(validate = len(6..))]
    // Указывает, что одно поле должно быть равно второму полю.
    #[field(validate = eq(self.second))]
    first: &'v str,
    //  Указывает, что второе поле должно быть равно одиночному полю.
    #[field(validate = eq(self.first))]
    second: &'v str,
}

// Опустите другие структуры и реализуйте...

// one обрабатывает запросы GET для определенной функции index,Возврат один Template объект.
// Эта функцияиспользовать используется для отображения домашней страницы.
#[get("/")]
fn index() -> Template {
    Template::render("index", &Context::default())
}

// one обрабатывает POST-запросы из-за определенной функции submit。
// Эта функция принимает один Form объект,в Включать Понятноформаизданные
#[post("/", data = "<form>")]
fn submit(form: Form<Submit<'_>>) -> (Status, Template) {
    // проходитьисследовать form.value да Содержит ли он Some(ref submission) Чтобы определить, отправлена ​​ли форма.
    let template = match form.value {
        // Если форма отправлена, распечатайте отправленное содержимое и отобразите его. "success" страница;
        Some(ref submission) => {
            println!("submission: {:#?}", submission);
            Template::render("success", &form.context)
        }
        // В противном случае визуализируйте "index" страница.
        None => Template::render("index", &form.context),
    };

    (form.context.status(), template)
}

// определение ПонятнозапускатьRocketотвечатьиспользоватьпрограммаизфункция。
#[launch]
fn rocket() -> _ {
    // делатьиспользовать rocket::build() Создать экземпляр приложения OneRocket, использовать экземпляр программы
    rocket::build()
        // и пройти .mount() Способ монтирования маршрутов.
        // routes![index, submit] Определены два маршрута,
        // соответственно сопоставлено с index и submit функция。
        .mount("/", routes![index, submit])
        // Добавлена ​​обработка одного шаблона изFairing (изmiddleware в Rocket)
        .attach(Template::fairing())
        // Волястатические файлы Служитьмонтировать накореньпуть。
        .mount("/", FileServer::from(relative!("/static")))
}

Характеристики ракеты

  • Комплексный подход.
  • Отличный опыт разработки.
  • Разработочная деятельность менее активна, чем раньше.
  • Отличный выбор для новичков.

4. Warp

Warp[7] даодинстроитьсуществовать Tokio Изначальствоиз Web Рамка, даодин, очень хорошее израмка. Он сильно отличается от других, которые мы видели раньше.

Warp и Axum Есть что-то общее из Функции: она строит существование. Tokio и Hyper выше и использовал Tower серединапромежуточное программное обеспечение。Однако,этосуществоватьметодначальство Существует большойиздругой。Warp да Учреждатьсуществовать Filter trait Изначальствоиз。

существовать Warp середина,яихстроитьсерияотвечатьиспользовать Ввходящийпроситьизфильтр,и Воляпроситьпередается в трубу, пока не будет достигнут конец。фильтр Могу связать,Их можно комбинировать. Это позволяет нам строить очень сложные трубопроводы.,но все равно легко понять.

Warp также, чем Axum ближе Tokio Экосистема, а это означает, что мы сможем справиться с большим количеством ситуаций без каких-либо обязательных свойств. Tokio Структура и концепция.

Warp Выбиратьиспользовать Очень функциональныйизметод,Если это стиль программирования,яих Волянравиться Warp из Выразительные способности и Композиционность. когда мы просматриваем Warp Фрагмент кода обычно читается как существование именно того, что произошло из истории, что существует Rust То, чего можно достичь в да, интересно и удивительно.

Однако,Благодаря этим различным функциям фильтры связаны друг с другом.,Warp серединаиз Типы становятся очень длинными и очень сложными.,И сложно понять. То же самое касается сообщения об ошибке,Да может быть трудно понять из-за большого объема текста.

Warp даодин великолепен.,это«Это не самый подходящий вариант для новичков и не самый популярный»。этотиметь в видуяих可能существоватьищу помощии Ресурсы будут сложнее。ноэто Очень«Подходит для быстрых небольших приложений»

Пример деформации

Со склада Примериз WebSocket Чат из Warp Процедуру следует упростить:

Язык кода:javascript
копировать
// определен одинстатикизированный атом usize прилавок,использовать Вдлякаждыйсоединятьизиспользовать Распределение счетов уникальноизиспользоватьсемьяID。
static NEXT_USER_ID: AtomicUsize = AtomicUsize::new(1);

// текущийсоединятьиспользоватьсемьяизсостояние。
//  определен один псевдоним типа Пользователи, это даодин атомарный кавычек использовать счетчик нечитаемой блокировки записи HashMap,ВоляиспользоватьсемьяIDкарта к сообщениюизотправлятьустройство。
// Arc ссылка на даатом использует счетчик интеллектуальных указателей, RwLock да блокировка чтения-записи.
// - идентификатор ключа
// - Значение da`warp::ws::Message`изsender
type Users = Arc<RwLock<HashMap<usize, mpsc::UnboundedSender<Message>>>>;

#[tokio::main]
async fn main() {
    // Создано один users Переменная,use используется для хранения информации о пользователе.
    let users = Users::default();
    // Воляит упакован как Warp Фильтруйте так, чтобы различные маршруты существовали совместно с использованием статуса пользователя.
    let users = warp::any().map(move || users.clone());

    // chat обработка маршрутизации WebSocket рукопожатие
    let chat = warp::path("chat")
        // `ws()`фильтр Воля ПодготовитьWebSocketрукопожатие...
        .and(warp::ws())
        .and(users)
        // настраиватьиспользовать user_connected функцияиметь дело с WebSocket соединять。
        .map(|ws: warp::ws::Ws, users| {
            // еслирукопожатиеуспех,Волянастраиватьиспользоватьяихизфункция。
            ws.on_upgrade(move |socket| user_connected(socket, users))
        });

    // иметь дело с HTTP GET просить,Возврат один Содержит ссылку на чат HTML страница
    let index = warp::path::end().map(|| warp::reply::html(INDEX_HTML));

    let routes = index.or(chat);

    warp::serve(routes).run(([127, 0, 0, 1], 3030)).await;
}


async fn user_connected(ws: WebSocket, users: Users) {
    // делатьиспользоватьприлавокдляэтотиспользоватьсемьявыделить новыеизтолькоID。
    let my_id = NEXT_USER_ID.fetch_add(1, Ordering::Relaxed);

    eprintln!("new chat user: {}", my_id);

    // Воляраскол розеткидляинформацияизотправлятьустройствоиполучатель。
    let (mut user_ws_tx, mut user_ws_rx) = ws.split();
    // Создать новый канал сообщений (mpsc::unbounded_channel) использовать ВВоляиспользоватьсемьяизинформация Трансляция другимиспользоватьсемья
    let (tx, rx) = mpsc::unbounded_channel();
    let mut rx = UnboundedReceiverStream::new(rx);

    tokio::task::spawn(async move {
        // Постоянно получать сообщения. Этот цикл будет завершен, как только пользователь отключится.
        while let Some(message) = rx.next().await {
            user_ws_tx
                .send(message)
                .unwrap_or_else(|e| {
                    eprintln!("websocket send error: {}", e);
                })
                .await;
        }
    });

    //Воляотправлятьустройстводержатьсуществоватьяихизужесоединятьиспользоватьсемьясписоксередина。
    users.write().await.insert(my_id, tx);

    // Возврат одинбазовыйначальстводауправлятьэтотидентификацияиспользоватьсемьясоединятьизсостояниемашинаиз“Future”。

    // в любое времяиспользоватьсемьяотправлятьинформациячас,Воляитс транслирует на
    // Все остальные используют домохозяйства...
    while let Some(result) = user_ws_rx.next().await {
        let msg = match result {
            Ok(msg) => msg,
            Err(e) => {
                eprintln!("websocket error(uid={}): {}", my_id, e);
                break;
            }
        };
        user_message(my_id, msg, &users).await;
    }

    // если бы толькоиспользоватьсемья Держатьсоединять,Поток user_ws_rx будет продолжаться дело с.Как только они отключатсоединять,Так...
    user_disconnected(my_id, &users).await;
}

// иметь дело сиспользоватьсемьяотправлятьизинформация。этопропустить нетекстинформация,Волятекстинформацияформатдля <User#ID>: Message,Затем Воляитс транслирует навседругойиспользоватьсемья。
async fn user_message(my_id: usize, msg: Message, users: &Users) {
    // Пропускать любые нетекстовые сообщения...
    let msg = if let Ok(s) = msg.to_str() {
        s
    } else {
        return;
    };

    let new_msg = format!("<User#{}>: {}", my_id, msg);

    // Приходитьсэтотиспользоватьсемьяизновыйинформация,Воля Чтоотправлять Даватьвседругойиспользоватьсемья(удалять Понятнотакой жеизuid)...
    for (&uid, tx) in users.read().await.iter() {
        if my_id != uid {
            if let Err(_disconnected) = tx.send(Message::text(new_msg.clone())) {
                // Передатчик был отключен для подключения, мы ввели код `user_disconnected`
                // Если будет выполнена еще одна миссия, делать здесь больше нечего.
            }
        }
    }
}

async fn user_disconnected(my_id: usize, users: &Users) {
    eprintln!("good bye user: {}", my_id);

    // Поток закрыт и поэтому удален из списка пользователей.
    users.write().await.remove(&my_id);
}

Функции

  • Метод функционального стиля.
  • Хорошие навыки выражения.
  • приближаясь TokioTower и Hyper Создайте мощную экосистему.
  • Не подходит для начинающих израмка

5. Tide

Tide[8] даодин Учреждатьсуществовать async-std 运行час Изначальствоиз«Минималистический веб-фреймворк»。минимализмизметодиметь в видуяих得приезжать Понятноодиночень маленькийиз API поверхность。Tide серединаизиметь дело сфункцияда async fn,приниматьодин Request и Возврат один Response из tide::Result。Извлечение данныхилиотправлятьправильныйизкольцоотвечать Отформатированояихс行完成。

Хотя для нас это может быть больше работы,но это также более прямолинейно,Это значит, что мы имеем полный контроль над происходящим. существуют в некоторых случаях,в состоянии уйти HTTP проситьикольцоотвечатьнравитьсяэтотзакрыватьдаудовольствие,Облегчает задачу.

Tide из метода Middleware и начнем с Tower Похоже на китайское слово из, но Tide Опубликовано async trait crate, что упрощает реализацию.

Пример прилива

Со склада Примеризиспользоватьсемьясессия Пример:

Язык кода:javascript
копировать
// async-std crate Обеспечить асинхронный main функция。это Возврат один Результат, указывающий на возможную ошибку.
#[async_std::main]
async fn main() -> Result<(), std::io::Error> {
    // делатьиспользовать femme crate Кай использовать цветной журнал. Эта даодинизированная библиотека журналирования делает вывод журнала более читабельным.
    femme::start();
    // Создать один Tide Пример приложения
    let mut app = tide::new();
    // Добавлено одно промежуточное программное обеспечение для журнала, позволяющее записывать запросы и ответы из информации журнала.
    app.with(tide::log::LogMiddleware::new());
    // добавить водинсессиясерединапромежуточное программное обеспечение,использовать Виметь дело сданные сеанса。этотвнутриделатьиспользовать Внутрижитьхранилище,и предоставьте один ключ (TIDE_SECRET),использовать для шифрования и проверки данных сеанса.
    app.with(tide::sessions::SessionMiddleware::new(
        tide::sessions::MemoryStore::new(),
        std::env::var("TIDE_SECRET")
            .ожидать(
                «Пожалуйста, укажите значение TIDE_SECRET в \
                      не менее 32 байтов для запуска этого примера",
            )
            .as_bytes(),
    ));
    // Добавляем один перед промежуточным программным обеспечением,этосуществоватьиметь дело спросить Доосуществлять。существоватьэтотвнутри,Ituse используется для увеличения количества посещений,хранилищесуществоватьсессиясередина。
    app.with(tide::utils::Before(
        |mut request: tide::Request<()>| async move {
            let session = request.session_mut();
            let visits: usize = session.get("visits").unwrap_or_default();
            session.insert("visits", visits + 1).unwrap();
            request
        },
    ));
    // определение Понятноодиниметь дело скорень Путь из запроса GET из маршрута. Этот маршрут проходит async move Приходитьиметь дело спросить,Получить количество доступов в сеансе,и Возврат один содержит количество посещений из строки.
    app.at("/").get(|req: tide::Request<()>| async move {
        let visits: usize = req.session().get("visits").unwrap();
        Ok(format!("you have visited this website {} times", visits))
    });
    // определение Понятноодиниметь дело с "/reset" Путь из запроса GET из маршрута. Этот маршрут проходит async move иметь дело спросить,Воляданные сеанса清удалять,Затемперенаправить накореньпуть
    app.at("/reset")
        .get(|mut req: tide::Request<()>| async move {
            req.session_mut().destroy();
            Ok(tide::Redirect::new("/"))
        });
    // запускатьотвечатьиспользоватьпрограммаимониторсуществовать "127.0.0.1:8080" адресначальство。делатьиспользовать await? иметь дело возможно неправильно иззапускаю.
    app.listen("127.0.0.1:8080").await?;

    Ok(())
}

Краткий обзор Тайда

  • Минималистский подход.
  • делатьиспользовать async-std время выполнения.
  • Простойизиметь дело сфункция。
  • Асинхронные функции на полигоне.

6. Poem

Poem[9] Утверждает, что он полностью функционален, но прост в использовании. Web рамка. На первый взгляд, это дает возможность использовать Axum очень похоже,толькоизразницадаэтонуждатьсяделатьиспользовать Взаимноотвечатьиз Макросотметкаиметь дело спрограммафункция。этовозвращаться Учреждатьсуществовать Tokio и Hyper выше, полностью совместим с Tower промежуточное программное обеспечение, но при этом подвергается воздействию функций промежуточного программного обеспечения.

Poem изсерединапромежуточное программное обеспечениехарактеристика也Очень Простойлегкийиспользовать。яих可以直接длявсеилиидентификацияиз Endpoint(Poem Выразите, что со всем можно справиться HTTP Метод запроса) для реализации этой возможности автору достаточно написать один Accept Endpoint делатьдляпараметризасинхронныйфункция。

Poem Он не только совместим со многими функциями более широкой экосистемы, но также обладает богатыми функциональными возможностями, включая поддержку OpenAPI и Swagger Документация и полная поддержка. это не ограничивается основе HTTP из Web услуги также можно использовать на основе Tonic из gRPC Служить,дажесуществовать Lambda функционировать без переключения кадров. добавить пару OpenTelemetryRedisPrometheus Как только из будет поддерживаться, мы сможем проверить все современные корпоративные приложения. Web оформить все коробки.

Poem все еще в 0.x версию, но если вы сохраните темп и добьетесь отличных результатов 1.0 Версия,этот Волядаодинценностьсосредоточиться наизрамка!

Пример стихотворения

Со склада Примериз WebSocket Чат изаббревиатура Версия:

Язык кода:javascript
копировать
// 注развязать表示этотдаодиниметь дело сустройствофункция,использовать Виметь дело с WebSocket просить
#[handler]
fn ws(
    // Извлечено WebSocket параметр isname в пути
    Path(name): Path<String>,
    // WebSocket объект, представление и клиент изоединять
    ws: WebSocket,
    // даодин экстрактор данных, используемый для получения канала вещания с передатчика.
    sender: Data<&tokio::sync::broadcast::Sender<String>>,
) -> impl IntoResponse {
    // Клонировать канал вещания из передатчика sender。
    let sender = sender.clone();
    // этоподписка Понятновещательный канал,Создано одинполучатель receiver
    let mut receiver = sender.subscribe();
    //  иметь дело с WebSocket соединятьобновление    ws.on_upgrade(move |socket| async move {
        // Волясоединятьиз разделения чтения и письма для sink и stream
        let (mut sink, mut stream) = socket.split();
        
        // от WebSocket Клиент получает сообщение
        // еслидатекстинформация,Потом Воля его форматировал под {name}: {text} изформа,и пройтивещательный каналотправлять。
        // Если отправка не удалась (например, канал закрыт), задача завершается.

        tokio::spawn(async move {
            while let Some(Ok(msg)) = stream.next().await {
                if let Message::Text(text) = msg {
                    if sender.send(format!("{name}: {text}")).is_err() {
                        break;
                    }
                }
            }
        });
        // отвещательный канал接收информация,и Воля Чтоотправлятьприезжать WebSocket клиент
        tokio::spawn(async move {
            while let Ok(msg) = receiver.recv().await {
                if sink.send(Message::Text(msg)).await.is_err() {
                    break;
                }
            }
        });
    })
}

#[tokio::main]
async fn main() -> Result<(), std::io::Error> {
    // делатьиспользовать tide::Route Создано одинмаршрутизация,ввключает в себя двапуть:
    // - / путьиметь дело с HTTP GET просить,настраиватьиспользовать index функция。
    // - /ws/:name путьиметь дело с WebSocket просить,настраиватьиспользовать ws функция。
    let app = Route::new().at("/", get(index)).at(
        "/ws/:name",
        // проходить tokio::sync::broadcast::channel Создать один канал вещания;
        // и пройти tokio::sync::broadcast::channel::<String>(32).0 
        //   获取Чтоотправлятьустройство,Воля Чтоделатьдляданные передаются в ws иметь дело сфункция
        get(ws.data(tokio::sync::broadcast::channel::<String>(32).0)),
    );
    // Создано одинсервер Примеры
    Server::new(TcpListener::bind("127.0.0.1:3000"))
         // запускатьсервер,и дождитесь завершения работы.
        .run(приложение)
        .жду
}

Краткий обзор стихотворения

  • Богатый набор функций.
  • и Tokio Совместимость с экосистемой.
  • легкий Вделатьиспользовать。
  • подходящийиспользовать В gRPC и Lambda。

постскриптум

как мы видим,Rust Web Мир рамкииз очень разнообразен. Не существует единого решения, подходящего для всех ситуаций, нам нужно выбрать то, которое лучше всего соответствует нашим потребностям. Если мы только начинаем, я предлагаю выбрать Actix или Axum,потому чтодляэтоихдабольшинствоподходящий Подходит для начинающихизрамка,ииэтоихиметь着Отличная документация.

«Поделитесь своим мнением»

«Весь текст окончен,Теперь, когда вы это увидели,Если ты чувствуешь себя хорошо,Смело ставьте лайк и «существовать к просмотру». "

Reference

[1]

Axum: https://github.com/tokio-rs/axum

[2]

Проект Токио: https://tokio.rs/

[3]

Hyper: https://hyper.rs/

[4]

Tower: https://docs.rs/tower/0.4.13/tower/

[5]

Actix Web: https://actix.rs/

[6]

Rocket: https://rocket.rs/

[7]

Warp: https://github.com/seanmonstar/warp

[8]

Tide: https://github.com/http-rs/tide

[9]

Poem: https://github.com/poem-web/poem

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose