The GatewayClient provides real-time event streaming through a WebSocket connection to the Fluxer gateway. It handles bidirectional communication, automatic heartbeats, and reconnection with resume capability.
The Gateway Client is responsible for:
using Fluxer.Net;
const string token = "YOUR_TOKEN_HERE";
var config = new FluxerConfig
{
// Optional configuration
ReconnectAttemptDelay = 10,
EnableRateLimiting = true
};
var gatewayClient = new GatewayClient(token, config);
Establishes a WebSocket connection to the Fluxer gateway and sends the IDENTIFY packet.
await gatewayClient.ConnectAsync();
This method:
Fires when the gateway connection is established and initial data is received. Contains session ID, user info, and initial guilds/channels/DMs.
gatewayClient.Ready += (data) =>
{
Console.WriteLine($"Bot ready! Logged in as {data.User.Username}");
Console.WriteLine($"Session ID: {data.SessionId}");
Console.WriteLine($"Connected to {data.Guilds.Count} guilds");
// Access initial data
foreach (var guild in data.Guilds)
{
Console.WriteLine($"Guild: {guild.Name} ({guild.Id})");
}
// Access user data
Console.WriteLine($"User ID: {data.User.Id}");
Console.WriteLine($"Email: {data.User.Email}");
};
Fires when a disconnected session is successfully resumed without data loss.
gatewayClient.Resumed += () =>
{
Console.WriteLine("Gateway connection resumed successfully!");
};
Fires when the gateway acknowledges a heartbeat packet (used for connection monitoring).
gatewayClient.HeartbeatAck += () =>
{
Console.WriteLine("Heartbeat acknowledged");
};
Fires when a new message is created in any channel the user has access to.
gatewayClient.MessageCreate += async (data) =>
{
var message = data.Message;
Console.WriteLine($"[{message.ChannelId}] {message.Author.Username}: {message.Content}");
// Check for attachments
if (message.Attachments?.Count > 0)
{
Console.WriteLine($" {message.Attachments.Count} attachment(s)");
}
// Check for embeds
if (message.Embeds?.Count > 0)
{
Console.WriteLine($" {message.Embeds.Count} embed(s)");
}
// Check for mentions
if (message.Mentions?.Count > 0)
{
Console.WriteLine($" Mentions: {string.Join(", ", message.Mentions.Select(u => u.Username))}");
}
};
Fires when a message is edited.
gatewayClient.MessageUpdate += (data) =>
{
Console.WriteLine($"Message {data.Message.Id} was edited");
Console.WriteLine($"New content: {data.Message.Content}");
};
Fires when a message is deleted.
gatewayClient.MessageDelete += (data) =>
{
Console.WriteLine($"Message {data.Id} was deleted from channel {data.ChannelId}");
};
// Channel created
gatewayClient.ChannelCreate += (data) =>
{
Console.WriteLine($"Channel created: {data.Channel.Name} ({data.Channel.Id})");
};
// Channel updated
gatewayClient.ChannelUpdate += (data) =>
{
Console.WriteLine($"Channel updated: {data.Channel.Name}");
};
// Channel deleted
gatewayClient.ChannelDelete += (data) =>
{
Console.WriteLine($"Channel deleted: {data.Channel.Name}");
};
// Guild created/became available
gatewayClient.GuildCreate += (data) =>
{
var guild = data.Guild;
Console.WriteLine($"Guild: {guild.Name} ({guild.MemberCount} members)");
};
// Guild updated
gatewayClient.GuildUpdate += (data) =>
{
Console.WriteLine($"Guild updated: {data.Guild.Name}");
};
// Guild deleted/became unavailable
gatewayClient.GuildDelete += (data) =>
{
Console.WriteLine($"Guild {data.Id} is no longer available");
};
// Member joined
gatewayClient.GuildMemberAdd += (data) =>
{
Console.WriteLine($"{data.Member.User.Username} joined guild {data.GuildId}");
};
// Member updated
gatewayClient.GuildMemberUpdate += (data) =>
{
Console.WriteLine($"Member {data.Member.User.Username} updated");
};
// Member left/removed
gatewayClient.GuildMemberRemove += (data) =>
{
Console.WriteLine($"Member {data.UserId} left guild {data.GuildId}");
};
gatewayClient.PresenceUpdate += (data) =>
{
Console.WriteLine($"{data.User.Username} is now {data.Status}");
Console.WriteLine($" Client Status: {data.ClientStatus}");
};
gatewayClient.TypingStart += (data) =>
{
Console.WriteLine($"{data.UserId} started typing in {data.ChannelId}");
};
gatewayClient.TypingStop += (data) =>
{
Console.WriteLine($"{data.UserId} stopped typing");
};
gatewayClient.MessageReactionAdd += (data) =>
{
Console.WriteLine($"Reaction added: {data.Emoji.Name} by {data.UserId}");
};
gatewayClient.MessageReactionRemove += (data) =>
{
Console.WriteLine($"Reaction removed: {data.Emoji.Name}");
};
Updates the current user's presence status on the gateway.
using Fluxer.Net.Data.Enums;
// Set status to Do Not Disturb
gatewayClient.SetStatus(Status.DoNotDisturb);
// Other statuses
gatewayClient.SetStatus(Status.Online);
gatewayClient.SetStatus(Status.Idle);
gatewayClient.SetStatus(Status.Invisible);
Sends a custom gateway packet to the Fluxer WebSocket server. Advanced users only.
var customPacket = new GatewayPacket
{
OpCode = FluxerOpCode.PresenceUpdate,
Data = new PresenceUpdateGatewayData(Status.Online)
};
gatewayClient.SendGatewayPacket(customPacket);
The Gateway Client automatically reconnects when the connection is lost and attempts to resume the session to prevent event loss.
When reconnecting, the client sends a RESUME packet with:
If the session can be resumed, you'll receive a RESUMED event. Otherwise, a new READY event is sent.
The Gateway Client handles Fluxer-specific close codes appropriately:
| Code | Name | Reconnect? |
|---|---|---|
| 4000 | Unknown Error | Yes |
| 4001 | Unknown Opcode | Yes (client bug) |
| 4002 | Decode Error | Yes (client bug) |
| 4003 | Not Authenticated | Yes |
| 4004 | Authentication Failed | No (invalid token) |
| 4005 | Already Authenticated | Yes |
| 4007 | Invalid Sequence | Yes (create new session) |
| 4008 | Rate Limited | Yes (with delay) |
| 4009 | Session Timeout | Yes (create new session) |
The GatewayClient implements IDisposable and should be properly disposed:
using var gatewayClient = new GatewayClient(token, config);
await gatewayClient.ConnectAsync();
// Client is automatically disposed when exiting the using block
Or manually:
gatewayClient.Dispose();
var readyReceived = new TaskCompletionSource();
gatewayClient.Ready += (data) =>
{
readyReceived.SetResult(true);
};
await gatewayClient.ConnectAsync();
await readyReceived.Task; // Wait for Ready before proceeding
var config = new FluxerConfig
{
IgnoredGatewayEvents = new List
{
"PRESENCE_UPDATE",
"TYPING_START",
"TYPING_STOP"
}
};
gatewayClient.MessageCreate += async (data) =>
{
try
{
// Your message handling code
}
catch (Exception ex)
{
Log.Error(ex, "Error handling message");
}
};