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.

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
    • 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

Create 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<()> {
    // Initialize the tracing subscriber.
    tracing_subscriber::fmt::init();

    let token = env::var("DISCORD_TOKEN")?;
    let intents = Intents::GUILDS | Intents::GUILD_VOICE_STATES;

    // Initialize the first and only shard in use by a bot.
    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 the error is fatal, as may be the case for invalid
                // authentication or intents, then break out of the loop to
                // avoid constantly attempting to reconnect.
                if source.is_fatal() {
                    break;
                }

                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, "received event");
    }

    Ok(())
}

Create the recommended number of shards and run them concurrently through ShardEventStream:

use futures::StreamExt;
use std::env;
use twilight_gateway::{
    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 config = Config::new(token, Intents::GUILDS);

    let mut shards = stream::create_recommended(&client, config, |_, builder| builder.build())
        .await?
        .collect::<Vec<_>>();

    // Create an infinite stream over the shards' events.
    let mut stream = ShardEventStream::new(shards.iter_mut());

    while let Some((shard, event)) = stream.next().await {
        let event = match event {
            Ok(event) => event,
            Err(source) => {
                tracing::warn!(?source, "error receiving event");

                if source.is_fatal() {
                    break;
                }

                continue;
            }
        };

        // You'd normally want to spawn a new tokio task for each event and
        // handle the event there to not block the shards.
        tracing::debug!(?event, shard = ?shard.id(), "received event");
    }

    Ok(())
}

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

Errors returned by gateway operations.
Utilities for managing collections of shards.

Structs

Information about a close message.
Ratelimiter for sending commands over the gateway to Discord.
Configuration used by the shard to identify with the gateway and operate.
Builder to customize the operation of a shard.
Important optimization for narrowing requested event types.
Inflaterzlib-stock or zlib-simd
Gateway event decompressor.
Gateway intents.
Shard’s gateway connection latency.
Channel to send messages over a Shard to the Discord gateway.
Gateway session information for a shard’s active connection.
Gateway API client responsible for up to 2500 guilds.
Shard identifier to calculate if it receivies a given event.

Enums

Current status of a shard.
Message to send over the connection to the remote.

Constants

Discord Gateway API version used by this crate.

Traits

Trait marker denoting what can be provided to Shard::command.

Functions

Parse a JSON encoded event into a gateway event if its type is in wanted_event_types.