68个版本
0.16.0-rc.1 | 2024年2月21日 |
---|---|
0.15.4 | 2023年9月10日 |
0.15.2 | 2023年4月27日 |
0.15.1 | 2023年2月26日 |
0.2.5 | 2020年11月29日 |
#98 in 网页编程
4,264 每月下载量
在 10 个软件包中使用 (9 个直接使用)
2.5MB
55K SLoC
twilight-gateway
twilight-gateway
是Discord分片网关会话的实现。它负责实时接收Discord的状态事件,并发送一些状态信息。
主要类型是 Shard
,这是一个维护与Discord网关的WebSocket连接的状态接口。其大部分功能都可以配置,并用于接收网关事件或原始WebSocket消息,这对于负载均衡和微服务很有用。
可以一次性轻松创建多个分片,使用 Fn(ShardId, ConfigBuilder) -> Config
闭包创建每个分片的自定义配置,借助 create_
系列函数。这些函数将重用分片的TLS上下文和[会话队列],否则需要通过克隆现有的 Config
来实现。
特性
simd-json
: 使用simd-json
替代serde_json
进行事件反序列化- TLS (互斥)
native-tls
: 通过native-tls
使用平台的本地TLS实现rustls-native-roots
(默认): 使用rustls
和本地根证书rustls-webpki-roots
: 使用rustls
和webpki-roots
根证书,对scratch
容器很有用
twilight-http
(默认): 启用stream::create_recommended
函数- zlib (互斥)
示例
创建推荐的分片数量,并并行遍历它们的公会事件
use std::{
env,
sync::atomic::{AtomicBool, Ordering},
};
use tokio::signal;
use twilight_gateway::{
error::ReceiveMessageErrorType, CloseFrame, Config, Event, EventTypeFlags, Intents, Shard,
StreamExt as _,
};
use twilight_http::Client;
static SHUTDOWN: AtomicBool = AtomicBool::new(false);
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let token = env::var("DISCORD_TOKEN")?;
let client = Client::new(token.clone());
let config = Config::new(token, Intents::GUILDS);
let shards =
twilight_gateway::create_recommended(&client, config, |_, builder| builder.build()).await?;
let mut senders = Vec::with_capacity(shards.len());
let mut tasks = Vec::with_capacity(shards.len());
for shard in shards {
senders.push(shard.sender());
tasks.push(tokio::spawn(runner(shard)));
}
signal::ctrl_c().await?;
SHUTDOWN.store(true, Ordering::Relaxed);
for sender in senders {
// Ignore error if shard's already shutdown.
_ = sender.close(CloseFrame::NORMAL);
}
for jh in tasks {
_ = jh.await;
}
Ok(())
}
async fn runner(mut shard: Shard) {
while let Some(item) = shard.next_event(EventTypeFlags::all()).await {
let event = match item {
Ok(Event::GatewayClose(_)) if SHUTDOWN.load(Ordering::Relaxed) => break,
Ok(event) => event,
Err(source)
if SHUTDOWN.load(Ordering::Relaxed)
&& matches!(source.kind(), ReceiveMessageErrorType::WebSocket) =>
{
break
}
Err(source) => {
tracing::warn!(?source, "error receiving event");
continue;
}
};
// You'd normally want to spawn a new tokio task for each event and
// handle the event there to not block the shard.
tracing::debug!(?event, shard = ?shard.id(), "received event");
}
}
更多示例位于 仓库 中。
依赖项
~9–23MB
~351K SLoC