TwitchLib.EventSub.Websockets 0.5.0-preview-ef96f7f

TwitchLib.EventSub.Websockets

TwitchLib component to connect to Twitch's EventSub service via Websockets also known as EventSockets

Disclaimer

EventSub via Websockets is still in open beta. You can use it in production but Twitch may introduce breaking changes without prior notice. The same goes for this implementation until it reaches Version 1.0.0

Prerequisites

  • Currently we only support setup via Dependency Injection

Resources

If you need help on how to setup Dependency Injection in your Console or WPF Application you can have a look at these guides:

You can also find a console app example for .NET 6 and for .NET Framework 4.8 in the repo.

Installation

NuGet TwitchLib.EventSub.Websockets
Package Manager PM> Install-Package TwitchLib.EventSub.Websockets -Version 0.4.0
.NET CLI > dotnet add package TwitchLib.EventSub.Websockets --version 0.4.0
PackageReference <PackageReference Include="TwitchLib.EventSub.Websockets" Version="0.4.0" />
Paket CLI > paket add TwitchLib.EventSub.Websockets --version 0.4.0

Setup

Step 1: Create a new project (Console, WPF, ASP.NET)

Step 2: Install the TwitchLib.EventSub.Websockets nuget package. (See above on how to do that)

Step 3: Step 3: Add necessary services and config to the DI Container

services.AddTwitchLibEventSubWebsockets();
services.AddHostedService<WebsocketHostedService>();

(The location of where to put this and the naming of variables might differ depending on what kind of project and general setup you have)

Step 4: Create the HostedService we just added to the DI container and connect to EventSub and listen to Events

using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using TwitchLib.EventSub.Websockets.Core.EventArgs;
using TwitchLib.EventSub.Websockets.Core.EventArgs.Channel;

namespace TwitchLib.EventSub.Websockets.Test
{
    public class WebsocketHostedService : IHostedService
    {
        private readonly ILogger<WebsocketHostedService> _logger;
        private readonly EventSubWebsocketClient _eventSubWebsocketClient;

        public WebsocketHostedService(ILogger<WebsocketHostedService> logger, EventSubWebsocketClient eventSubWebsocketClient)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));

            _eventSubWebsocketClient = eventSubWebsocketClient ?? throw new ArgumentNullException(nameof(eventSubWebsocketClient));
            _eventSubWebsocketClient.WebsocketConnected += OnWebsocketConnected;
            _eventSubWebsocketClient.WebsocketDisconnected += OnWebsocketDisconnected;
            _eventSubWebsocketClient.WebsocketReconnected += OnWebsocketReconnected;
            _eventSubWebsocketClient.ErrorOccurred += OnErrorOccurred;

            _eventSubWebsocketClient.ChannelFollow += OnChannelFollow;
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            await _eventSubWebsocketClient.ConnectAsync();
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            await _eventSubWebsocketClient.DisconnectAsync();
        }

        private void OnWebsocketConnected(object? sender, WebsocketConnectedArgs e)
        {
            _logger.LogInformation($"Websocket {_eventSubWebsocketClient.SessionId} connected!");

            if (!e.IsRequestedReconnect)
            {
                // subscribe to topics
            }
         }

        private async void OnWebsocketDisconnected(object? sender, EventArgs e)
        {
            _logger.LogError($"Websocket {_eventSubWebsocketClient.SessionId} disconnected!");

            // Don't do this in production. You should implement a better reconnect strategy with exponential backoff
            while (!await _eventSubWebsocketClient.ReconnectAsync())
            {
                _logger.LogError("Websocket reconnect failed!");
                await Task.Delay(1000);
            }
        }

        private void OnWebsocketReconnected(object? sender, EventArgs e)
        {
            _logger.LogWarning($"Websocket {_eventSubWebsocketClient.SessionId} reconnected");
        }      
      
         private void OnErrorOccurred(object? sender, ErrorOccuredArgs e)
        {
            _logger.LogError($"Websocket {_eventSubWebsocketClient.SessionId} - Error occurred!");
        }

        private void OnChannelFollow(object? sender, ChannelFollowArgs e)
        {
            var eventData = e.Notification.Payload.Event;
            _logger.LogInformation($"{eventData.UserName} followed {eventData.BroadcasterUserName} at {eventData.FollowedAt}");
        }
    }
}

Alternatively you can also just clone the examples:

No packages depend on TwitchLib.EventSub.Websockets.

Updated TwitchLib.EventSub.Core for the latest SubscriptionType changes

Version Downloads Last updated
0.8.0 6 12/14/2025
0.8.0-preview.89.6e10e27 5 02/09/2026
0.8.0-preview.87.3ff8932 6 12/15/2025
0.8.0-preview.86.edf4f1c 6 12/15/2025
0.8.0-preview.85.9f998d3 6 12/15/2025
0.7.0 9 10/27/2025
0.7.0-preview.80.7583c0f 8 10/27/2025
0.7.0-preview.79.47f9402 9 09/09/2025
0.7.0-preview.78.d5d3fa8 9 09/09/2025
0.7.0-preview.77.43b8abc 9 09/09/2025
0.7.0-preview.76.e0eb3c4 10 07/29/2025
0.7.0-preview.75.9626728 10 07/29/2025
0.7.0-preview.74.00871ba 9 07/29/2025
0.7.0-preview.73.af00daa 10 07/29/2025
0.7.0-preview.72.d91d48d 10 07/29/2025
0.7.0-preview.71.3864955 10 07/29/2025
0.7.0-preview.70.cd91499 12 06/22/2025
0.6.0 11 06/22/2025
0.6.0-preview-f14064f 10 05/22/2025
0.6.0-preview-dbc970c 15 02/19/2025
0.6.0-preview-cde682a 14 02/19/2025
0.6.0-preview-9e27637 11 06/22/2025
0.6.0-preview-8dbcfb5 11 05/22/2025
0.6.0-preview-6f4cd77 14 02/19/2025
0.6.0-preview-62.534d542 11 06/22/2025
0.6.0-preview-532b5cd 10 05/22/2025
0.6.0-preview-3c5fac1 11 05/22/2025
0.6.0-preview-129f195 14 02/19/2025
0.6.0-preview.67.4401bf1 11 06/22/2025
0.6.0-preview.66.3e5313f 11 06/22/2025
0.5.0 14 02/19/2025
0.5.0-preview-ffc3181 14 02/19/2025
0.5.0-preview-ff1356d 14 02/19/2025
0.5.0-preview-fed1002 13 02/19/2025
0.5.0-preview-ef96f7f 14 02/19/2025
0.5.0-preview-d22efe0 14 02/19/2025
0.5.0-preview-cf9adcd 14 02/19/2025
0.5.0-preview-bcfc70a 14 02/19/2025
0.5.0-preview-bcc5801 14 02/19/2025
0.5.0-preview-abba5e7 14 02/19/2025
0.5.0-preview-a6ae325 14 02/19/2025
0.5.0-preview-72088d1 15 02/19/2025
0.5.0-preview-50e75fa 14 02/19/2025
0.5.0-preview-38d6070 15 02/19/2025
0.5.0-preview-10a6910 14 02/19/2025
0.4.0 14 02/19/2025
0.4.0-preview-7595d8b 14 02/19/2025
0.3.0 14 02/19/2025
0.3.0-preview-f4eee33 16 02/19/2025
0.3.0-preview-4523dce 13 02/19/2025
0.3.0-preview-34c0d87 13 02/19/2025
0.3.0-preview-13e1cef 14 02/19/2025
0.2.0 13 02/19/2025
0.2.0-preview-e561e8e 13 02/19/2025
0.2.0-preview-24aeaba 14 02/19/2025
0.1.0 14 02/19/2025
0.1.0-preview-ce4fc65 15 02/19/2025
0.1.0-preview-a65fad9 14 02/19/2025
0.1.0-preview-29bcaac 14 02/19/2025
0.1.0-preview-17203fa 14 02/19/2025
0.0.3 15 01/27/2025
0.0.3-preview-5d9eb3d 15 02/19/2025
0.0.2 14 02/19/2025
0.0.2-preview-d1dbff3 14 02/19/2025
0.0.2-preview-66f945c 14 02/19/2025
0.0.2-preview-1038807 14 02/19/2025