TwitchLib.EventSub.Websockets 0.1.0-preview-a65fad9

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.1.0
.NET CLI > dotnet add package TwitchLib.EventSub.Websockets --version 0.1.0
PackageReference <PackageReference Include="TwitchLib.EventSub.Websockets" Version="0.1.0" />
Paket CLI > paket add TwitchLib.EventSub.Websockets --version 0.1.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, Switched to .NET 7.0 Full Release build, Fixed README

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