28个版本 (8个破坏性)
| 0.10.0 |
|
|---|---|
| 0.9.4 | 2023年5月2日 |
| 0.9.3 | 2023年3月13日 |
| 0.7.0-beta.3 | 2022年12月21日 |
| 0.3.0 | 2022年11月30日 |
#42 in #cookies
每月82次下载
81KB
2K SLoC
axum-cometd
lib.rs:
此crate旨在使在用Rust编写的服务器中使用CometD协议成为可能。
此项目正在进行中,版本之间可能会有很大变化。
目录
服务器端点
服务器有4个端点
/handshake-- 注册并获取clientId;/-- 订阅频道;/connect-- 接收或发布消息;/disconnect-- 告诉服务器清理clientId的数据;
您可以通过 RouterBuilder::handshake_base_path、RouterBuilder::subscribe_base_path、RouterBuilder::connect_base_path、RouterBuilder::disconnect_base_path 改变这些端点的基准部分。例如,要使 /node/0/handshake 和 /node/1/connect,您可以这样做
use std::sync::Arc;
use axum_cometd::{LongPollingServiceContextBuilder, RouterBuilder};
let context = LongPollingServiceContextBuilder::new()
.build();
let router = RouterBuilder::new()
.handshake_base_path("/node/0")
.connect_base_path("/node/1")
.build(Arc::clone(&context));
clientId 和 BAYEUX_BROWSER cookie
clientId 和 BAYEUX_BROWSER cookie 是长度为40的十六进制字符串,可能以零开头。如果它不是这样,服务器将返回 '402::session_unknown' 错误。为了获得一些唯一性,首先从Unix时间戳中取出前8个字节,然后使用随机数填充最后部分。
服务器如何工作
BAYEUX_BROWSER cookie 将在 /handshake 请求中生成和设置,如果还没有的话。
在其他端点([服务器端点])中,服务器检查 clientId 和 BAYEUX_BROWSER 糖果(如果向 /connect 发送消息,则将检查每个 clientId)。如果 clientId 与不同的 BAYEUX_BROWSER 糖果一起使用,则服务器将返回 '402::session_unknown' 错误。
如何获取服务器事件
服务器有 3 个事件
SessionAdded 和 Subscribe 可以包含附加数据,这些数据将通过 axum::Extension 附加。要获取这些事件,您必须使用获取接收通道 LongPollingServiceContext::rx。服务器不使用 Event::CustomData,它使用自定义消息,该消息可以在接收器中接收。
use std::sync::Arc;
use axum::Extension;
use axum_cometd::{LongPollingServiceContextBuilder, RouterBuilder};
#[derive(Debug, Clone)]
struct ContextData {
server_name: Arc<str>,
}
use std::time::Duration;
use axum_cometd::Event;
let context = LongPollingServiceContextBuilder::new()
.build::<ContextData, &'static str>();
let app = RouterBuilder::new()
.build_with_additional_data(Arc::clone(&context))
.layer(Extension(ContextData {
server_name: std::env::var("SERVER_NAME")
.map(Arc::from)
.unwrap_or_else(|_| Arc::from("Skalica")),
}));
let tx = context.tx();
let mut rx = context.rx();
tokio::task::spawn(async move {
loop {
tx.send("CUSTOM_DATA").await;
tokio::time::sleep(Duration::from_secs(1)).await;
}
});
while let Some(event) = rx.recv().await {
match *event {
Event::SessionAdded{
client_id,
ref headers,
ref data,
} => {
println!("sessionAdded with clientId({client_id}), headers({headers:?}), data({data:?})");
}
Event::Subscribe{
client_id,
ref headers,
ref channels,
ref data,
} => {
println!("subscribed on channels({channels:?}) with clientId({client_id}), headers({headers:?}), data({data:?})");
}
Event::SessionRemoved{
client_id,
} => println!("clientId({client_id}) session removed"),
Event::CustomData(msg) => println!("got CustomData({msg})"),
}
}
依赖关系
~14MB
~263K SLoC