Crate twilight_gateway

Source
Expand description

§twilight-gateway

codecov badge discord badge github badge license badge rust badge

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 gateway events or raw Websocket messages, useful for load balancing and microservices.

Multiple shards may easily be created at once, with a per shard config created from a Fn(ShardId, ConfigBuilder) -> Config closure, with the help of the create_ set of functions. These functions will reuse shards’ TLS context and session queue, something otherwise achieved by cloning an existing Config.

§Features

  • simd-json: use simd-json instead of serde_json for deserializing events
  • TLS (mutually exclusive)
    • native-tls: platform’s native TLS implementation via native-tls
    • rustls-native-roots: rustls using native root certificates
    • rustls-platform-verifier (default): rustls using operating system’s certificate facilities via rustls-platform-verifier
    • rustls-webpki-roots: rustls using webpki-roots for root certificates, useful for scratch containers
  • Crypto providers (required with rustls)
    • rustls-ring (default): ring as the crypto provider, recommended for compatibility
    • rustls-aws_lc_rs: aws-lc-rs as the crypto provider, recommended for performance and widely used platforms
    • none of the above: install your own via CryptoProvider::install_default
  • twilight-http (default): enable the stream::create_recommended function
  • Compression (mutually exclusive)
    • zlib-stock: flate2’s stock zlib implementation (deprecated)
    • zlib-simd: use zlib-ng for zlib, may have better performance (deprecated)
    • zstd (default): enable zstd transport compression

§Example

Create the recommended number of shards and loop over their guild events in parallel

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(())
}

#[tracing::instrument(fields(shard = %shard.id()), skip_all)]
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) => {
                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");
    }
}

There are a few additional examples located in the repository.

Re-exports§

pub use twilight_gateway_queue as queue;
pub use twilight_model::gateway::event::Event;
pub use twilight_model::gateway::event::EventType;

Modules§

error
Errors returned by gateway operations.

Structs§

CloseFrame
Information about a close message.
CommandRatelimiter
Ratelimiter for sending commands over the gateway to Discord.
Config
Configuration used by the shard to identify with the gateway and operate.
ConfigBuilder
Builder to customize the operation of a shard.
EventTypeFlags
Important optimization for narrowing requested event types.
Intents
Gateway intents.
Latency
Shard’s gateway connection latency.
MessageSender
Channel to send messages over a Shard to the Discord gateway.
Session
Gateway session information for a shard’s active connection.
Shard
Gateway API client responsible for up to 2500 guilds.
ShardId
Shard identifier to calculate if it receivies a given event.

Enums§

Message
Message to send over the connection to the remote.
ShardState
Current state of a Shard.

Constants§

API_VERSION
Discord Gateway API version used by this crate.

Traits§

Command
Trait marker denoting what can be provided to Shard::command.
StreamExt
An extension trait for the [Stream] trait.

Functions§

create_bucket
Create a single bucket’s worth of shards.
create_iterator
Create a iterator of shards.
create_recommendedtwilight-http
Create a range of shards from Discord’s recommendation.
parse
Parse a JSON encoded gateway event into a GatewayEvent if wanted_event_types contains its type.