前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rust:axum学习笔记(6) SSE(Server Send Event)服务端推送

Rust:axum学习笔记(6) SSE(Server Send Event)服务端推送

作者头像
菩提树下的杨过
发布2022-04-27 10:56:14
1.1K0
发布2022-04-27 10:56:14
举报

上一篇继续,SSE也就是服务端推送技术,自html5推出以来基本上各大浏览器都已支持,axum自然也支持,参考下面的代码:

async fn sse_handler(
    TypedHeader(user_agent): TypedHeader<headers::UserAgent>,
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
    println!("`{}` connected", user_agent.as_str());

    let mut i = 0;
    // A `Stream` that repeats an event every second
    let stream = stream::repeat_with(move || {
        i += 1;
        Event::default().data(format!("hi,{}", &i))
    })
    .map(Ok)
    .throttle(Duration::from_secs(3)); //每3秒,向浏览器发1次消息

    //每隔1秒发1次保活
    Sse::new(stream).keep_alive(
        axum::response::sse::KeepAlive::new()
            .interval(Duration::from_secs(1))
            .text("keep-alive-text"),
    )
}

上面的代码,表示每3秒向浏览器发1次消息,每秒发1次keep-alive保活,完整代码如下:

cargo.toml

[package]
name = "sse"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
axum =  {version = "0.4.3", features = ["headers"] }
tokio = { version = "1.0", features = ["full"] }
tower-http = { version = "0.2.0", features = ["fs", "trace"] }
futures = "0.3"
tokio-stream = "0.1"
headers = "0.3"

 main.rs

use axum::{
    extract::TypedHeader,
    response::sse::{Event, Sse},
    routing::get,
    Router,
};
use futures::stream::{self, Stream};
use std::{convert::Infallible, net::SocketAddr, time::Duration};
use tokio_stream::StreamExt as _;

#[tokio::main]
async fn main() {
    // build our application with a route
    let app = Router::new()
        .route("/sse", get(sse_handler))
        .route("/", get(|| async { "Hello, World!" }));

    // run it
    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    axum::Server::bind(&addr)
        .serve(app.into_make_service())
        .await
        .unwrap();
}

async fn sse_handler(
    TypedHeader(user_agent): TypedHeader<headers::UserAgent>,
) -> Sse<impl Stream<Item = Result<Event, Infallible>>> {
    println!("`{}` connected", user_agent.as_str());

    let mut i = 0;
    // A `Stream` that repeats an event every second
    let stream = stream::repeat_with(move || {
        i += 1;
        Event::default().data(format!("hi,{}", &i))
    })
    .map(Ok)
    .throttle(Duration::from_secs(3)); //每3秒,向浏览器发1次消息

    //每隔1秒发1次保活
    Sse::new(stream).keep_alive(
        axum::response::sse::KeepAlive::new()
            .interval(Duration::from_secs(1))
            .text("keep-alive-text"),
    )
}

运行效果:

先访问http://localhost:3000/ 然后在浏览器的console控制台,输入以下js:

var eventSource = new EventSource('/sse');

eventSource.onmessage = function(event) {
    console.log('Message from server ', event.data);
}

顺利的话,就能看到控制台不断输出服务端推送过来的数据:

切换到Network面板,可以看到/sse返回的content-type为text/event-stream

如果是chrome浏览器,直接访问/sse,还能看到keep-alive的动态输出

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档