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


    上一篇继续,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的动态输出

  • 相关阅读:
    poj 3026 Borg Maze
    poj2828 Buy Tickets
    poj3264 Balanced Lineup
    高精度运算
    poj1035 Spell checker
    poj2318 TOYS 点积叉积理解
    求两直线交点的一般做法
    C语言I博客作业05
    C语言I博客作业04
    C语言I博客作业07
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/axum_tutorial_6_sse.html
Copyright © 2020-2023  润新知