53 个版本

0.26.2 2024 年 4 月 2 日
0.26.0 2023 年 10 月 11 日
0.25.3 2023 年 9 月 4 日
0.22.20 2023 年 7 月 29 日
0.7.0 2021 年 2 月 27 日

#30 in #kerberos

Download history 33/week @ 2024-04-15 45/week @ 2024-04-22 48/week @ 2024-04-29 31/week @ 2024-05-06 32/week @ 2024-05-13 53/week @ 2024-05-20 46/week @ 2024-05-27 44/week @ 2024-06-03 48/week @ 2024-06-10 51/week @ 2024-06-17 43/week @ 2024-06-24 27/week @ 2024-07-08 57/week @ 2024-07-15 26/week @ 2024-07-22 43/week @ 2024-07-29

每月下载量 153
用于 19crate(14 个直接使用)

MIT 许可证

105KB
3K SLoC

Crates.io docs.rs MIT licensed

什么是 Netidx

Netidx 是一种中间件,它允许在一个程序中发布一个值(例如 42),并在另一个程序中消费它,无论是在同一台机器上还是在网络上的另一台机器上。

值在分层命名空间中具有全局唯一名称。例如,我们发布的 42 可能被命名为 /the-ultimate-answer(通常我们不会直接在根目录下放置值,但在这个例子中是合适的)。网络上的任何其他程序都可以通过该名称引用 42,并且如果在 /the-ultimate-answer 发生变化的情况下,将接收到更新。

与其他系统的比较

  • 类似于 LDAP

    • Netidx 跟踪值的分层目录
    • Netidx 在一定程度上可浏览和可查询
    • Netidx 支持身份验证、授权和加密
    • Netidx 值可以读写。
    • 可以通过在较小系统之间添加引用来构建较大的 Netidx 系统。解析服务器集群可能有父级和子级。
  • 与 LDAP 不同

    • 在 Netidx 中,解析服务器(如 slapd)仅保留具有数据的发布者的位置,而不是数据本身。
    • 没有“条目”、“属性”、“ldif 记录”等。系统中的每个名称要么是结构性的,要么是单个值。使用分层创建类似于条目的结构。因此,也没有模式检查。
    • 可以订阅一个值,如果它发生变化,则会立即通知。
    • 没有全局数据过滤器,例如,不能查询 (&(cn=bob)(uid=foo)),因为 Netidx 不是一个数据库。是否存在和什么查询机制取决于发布者。然而,可以查询结构,例如 /foo/**/bar 将返回任何以 bar 结尾的 foo 下的路径。
  • 类似于 MQTT

    • Netidx 值是发布/订阅
    • 单个 Netidx 值可以有多位订阅者
    • 当订阅的值发生变化时,所有 Netidx 订阅者都会收到更新。
    • Netidx 消息传递是可靠和有序的。
  • 与 MQTT 不同

    • Netidx 中没有中心化的消息代理。消息直接通过 TCP 从发布者流向订阅者。解析器服务器仅存储发布者/发布值的地址。

更多详情请参阅netidx 书籍

以下是一个示例服务,该服务发布 CPU 温度,以及相应的订阅者,用于消费数据。

发布者

use netidx::{
    publisher::{Publisher, Value, BindCfg},
    config::Config,
    resolver::Auth,
    path::Path,
};
use tokio::time;
use std::time::Duration;
use anyhow::Result;

fn get_cpu_temp() -> f32 { 42. }

async fn run() -> Result<()> {
    // load the site cluster config. You can also just use a file.
    let cfg = Config::load_default()?;

    // no authentication (kerberos v5 is the other option)
    // listen on any unique address matching 192.168.0.0/16
    let publisher = Publisher::new(cfg, Auth::Anonymous, "192.168.0.0/16".parse()?).await?;

    let temp = publisher.publish(
        Path::from("/hw/washu-chan/cpu-temp"),
        Value::F32(get_cpu_temp())
    )?;

    loop {
        time::sleep(Duration::from_millis(500)).await;
        let mut batch = publisher.start_batch();
        temp.update(&mut batch, Value::F32(get_cpu_temp()));
        batch.commit(None).await;
    }
    Ok(())
}

订阅者

use netidx::{
    subscriber::{Subscriber, UpdatesFlags},
    config::Config,
    resolver::Auth,
    path::Path,
};
use futures::{prelude::*, channel::mpsc};
use anyhow::Result;

async fn run() -> Result<()> {
    let cfg = Config::load_default()?;
    let subscriber = Subscriber::new(cfg, Auth::Anonymous)?;
    let path = Path::from("/hw/washu-chan/cpu-temp");
    let temp = subscriber.subscribe_one(path, None).await?;
    println!("washu-chan cpu temp is: {:?}", temp.last());

    let (tx, mut rx) = mpsc::channel(10);
    temp.updates(UpdatesFlags::empty(), tx);
    while let Some(mut batch) = rx.next().await {
        for (_, v) in batch.drain(..) {
            println!("washu-chan cpu temp is: {:?}", v);
        }
    }
    Ok(())
}

发布的对象始终有一个值,新订阅者最初接收该值。此后,订阅是一个无损有序流,就像 TCP 连接一样,只不过传输单位是 publisher::Value 而不是字节。由于订阅者可以回写值给发布者,因此连接是双向的,就像 Tcp 流一样。

值包括许多有用的原语,包括零拷贝的字节缓冲区(使用神奇的 bytes crate),因此您可以使用 netidx 高效地发送任何类型的消息。然而,建议您坚持使用原语,并通过在层次结构中使用多个发布值来表示结构,因为这可以使您的系统更易于发现,并且效率也相当高。

netidx 包含对 Kerberos v5(包括 Active Directory)的可选支持。如果启用,所有组件将在解析器、订阅者和发布者之间进行相互身份验证,并加密所有传输数据。

在 krb5 模式下,解析器服务器维护并执行整个命名空间的授权权限集。系统管理员可以集中执行谁可以发布到何处,以及谁可以订阅什么。

依赖关系

~7–14MB
~142K SLoC