zenoh webserver 插件一个有意思的功能

zenoh webserver plugin 是可以获取key 的信息,通过http 协议实现资源的映射,同时zenoh对于key 支持查询参数,比如SUB 可以实现流式数据处理 ,比如视频以及多媒体资源类的处理

流式请求格式

<key_expre>?_method=SUB 使用此格式,可以实现流式处理

实时流处理使用到的技术

内部并没有什么特殊的,就是使用了一个http 的mine type multipart/x-mixed-replace ,具体介绍可以参考以下链接

  • zenoh 内部处理

机制上是利用了创建了zenoh 的订阅,并通过multipart/x-mixed-replace 数据格式进行http输出


if selector.parameters().get("_method") == Some("SUB") {
    tracing::debug!("Subscribe to {} for Multipart stream", selector.key_expr());
    let (sender, mut receiver) = tokio::sync::mpsc::channel(1);
    let c_selector = selector.key_expr().clone().into_owned();
    spawn_runtime(async move {
        tracing::debug!("Subscribe to {} for Multipart stream", c_selector);
        let sub = req.state().declare_subscriber(c_selector).await.unwrap();
        loop {
            let sample = sub.recv_async().await.unwrap();
            let mut buf = "--boundary\nContent-Type: ".as_bytes().to_vec();
            buf.extend_from_slice(sample.encoding().to_string().as_bytes());
            buf.extend_from_slice("\n\n".as_bytes());
            buf.extend_from_slice(sample.payload().to_bytes().as_ref());

            match tokio::time::timeout(
                std::time::Duration::new(10, 0),
                sender.send(Ok(buf)),
            )
            .await
            {
                Ok(Ok(_)) => {}
                Ok(Err(e)) => {
                    tracing::debug!(
                        "Multipart error ({})! Unsubscribe and terminate",
                        e
                    );
                    if let Err(e) = sub.undeclare().await {
                        tracing::error!("Error undeclaring subscriber: {}", e);
                    }
                    break;
                }
                Err(_) => {
                    tracing::debug!("Multipart timeout! Unsubscribe and terminate",);
                    if let Err(e) = sub.undeclare().await {
                        tracing::error!("Error undeclaring subscriber: {}", e);
                    }
                    break;
                }
            }
        }
    });

    let receiver = async_stream::stream! {
          while let Some(item) = receiver.recv().await {
              yield item;
          }
    };
    let mut res = Response::new(StatusCode::Ok);
    res.set_content_type("multipart/x-mixed-replace; boundary=\"boundary\"");
    res.set_body(tide::Body::from_reader(
        Box::pin(receiver.into_async_read()),
        None,
    ));

    Ok(res)
}

说明

zenoh 对于实时流媒体的支持内部核心还是利用了zenoh 的订阅能力,同时使用了标准http 协议提供的支持,基于此特性可以实现一些比较有意思的东西,比如监控,播放等,但是注意zenoh 是可以传输流媒体的,但是对于部署环境带宽占用会特别多,实际使用此特性的时候

注意部署的实际资源情况,否则效果不太好,同时影响zenoh 的稳定性

参考资料

https://github.com/eclipse-zenoh/zenoh-plugin-webserver

https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html

https://stackoverflow.com/questions/65603894/multipart-x-mixed-replace-png-stream-always-showing-frame-before-last

posted on   荣锋亮  阅读(19)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2024-01-02 wasmex webassenbly elixir 运行时
2024-01-02 oban简单学习试用
2023-01-02 nginx-clojure docker 镜像
2023-01-02 dremio NamespaceService 简单说明一
2023-01-02 dremio 的加速文件系统插件简单说明
2023-01-02 dremio ClassPathScanner 简单说明
2023-01-02 dremio formatPlugin 调用链

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示