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