28 个版本 (14 个重大更新)
0.26.2 | 2024 年 4 月 2 日 |
---|---|
0.26.0 | 2023 年 10 月 11 日 |
0.25.0 | 2023 年 8 月 30 日 |
0.22.0 | 2023 年 6 月 25 日 |
0.7.0 | 2021 年 2 月 27 日 |
#1160 in 网络编程
每月 129 次下载
被 16 个 Crates (5 个直接引用) 使用
245KB
6.5K SLoC
什么是 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模式下,解析服务器维护并强制实施整个命名空间的一组授权权限。系统管理员可以集中执行谁可以发布到何处,以及谁可以订阅什么。
依赖项
~10–18MB
~227K SLoC