twilight-gateway
twilight-gateway
is an implementation of Discord's sharding gateway sessions.
This is responsible for receiving stateful events in real-time from Discord
and sending some stateful information.
The primary type is the Shard
, a stateful interface to maintain a Websocket
connection to Discord's gateway. Much of its functionality can be configured, and
it's used to receive deserialized gateway event payloads or raw Websocket
messages, useful for load balancing and microservices.
Using the stream
module, shards can be easily managed in groups.
Features
simd-json
: use simd-json
instead of serde_json
for deserializing
events
- TLS (mutually exclusive)
native
: platform's native TLS implementation via native-tls
equivalents
rustls-native-roots
(default): rustls
using native root certificates
rustls-webpki-roots
: rustls
using webpki-roots
for root
certificates, useful for scratch
containers
twilight-http
(default): enable the stream::create_recommended
function
- Zlib (mutually exclusive)
zlib-stock
(default): [flate2
]'s stock zlib implementation
zlib-ng
: use zlib-ng
for zlib, may have better performance
Examples
Start a shard and loop over guild and voice state events:
use std::env;
use twilight_gateway::{Intents, Shard, ShardId};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let token = env::var("DISCORD_TOKEN")?;
let intents = Intents::GUILDS | Intents::GUILD_VOICE_STATES;
let mut shard = Shard::new(ShardId::ONE, token, intents);
tracing::info!("started shard");
loop {
let event = match shard.next_event().await {
Ok(event) => event,
Err(source) => {
tracing::warn!(?source, "error receiving event");
if source.is_fatal() {
break;
}
continue;
},
};
tracing::debug!(?event, "received event");
}
Ok(())
}
Create the recommended number of shards and stream over their events:
use futures::StreamExt;
use std::{collections::HashMap, env, sync::Arc};
use twilight_gateway::{
queue::LocalQueue,
stream::{self, ShardEventStream},
Config, Intents,
};
use twilight_http::Client;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let token = env::var("DISCORD_TOKEN")?;
let client = Client::new(token.clone());
let queue = Arc::new(LocalQueue::new());
let config_callback = |_| {
Config::builder(token.clone(), Intents::GUILDS)
.queue(queue.clone())
.build()
};
let mut shards = stream::create_recommended(&client, config_callback)
.await?
.collect::<Vec<_>>();
let mut stream = ShardEventStream::new(shards.iter_mut());
loop {
let (shard, event) = match stream.next().await {
Some((shard, Ok(event))) => (shard, event),
Some((_, Err(source))) => {
tracing::warn!(?source, "error receiving event");
if source.is_fatal() {
break;
}
continue;
},
None => break,
};
tracing::debug!(?event, shard = ?shard.id(), "received event");
}
Ok(())
}
There are a few additional examples located in the
repository.