Skip to content

Commit 663f3c8

Browse files
authored
Merge pull request #60 from TwitchLib/dev
[release] v0.6.0
2 parents c10be94 + 4401bf1 commit 663f3c8

File tree

50 files changed

+1071
-237
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1071
-237
lines changed

.github/workflows/preview-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111

1212
steps:
1313
- uses: actions/checkout@v4
14-
- uses: benjlevesque/short-sha@v2.2
14+
- uses: benjlevesque/short-sha@v3.0
1515
id: short-sha
1616
- name: Setup .NET
1717
uses: actions/setup-dotnet@v3
@@ -22,6 +22,6 @@ jobs:
2222
- name: Build TwitchLib.EventSub.Websockets
2323
run: dotnet build -c Release --no-restore
2424
- name: Pack TwitchLib.EventSub.Websockets
25-
run: dotnet pack ./TwitchLib.EventSub.Websockets/TwitchLib.EventSub.Websockets.csproj -v normal -c Release -o nugets --no-build --version-suffix "preview-${{ steps.short-sha.outputs.sha }}"
25+
run: dotnet pack ./TwitchLib.EventSub.Websockets/TwitchLib.EventSub.Websockets.csproj -v normal -c Release -o nugets --no-build --version-suffix "preview.${{ github.run_number }}.${{ steps.short-sha.outputs.sha }}"
2626
- name: Push to Nuget
2727
run: dotnet nuget push "./nugets/*.nupkg" -k ${{ secrets.API_NUGET_TOKEN }} -s https://api.nuget.org/v3/index.json

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ You can also find a console app example for .NET 8 and for .NET Framework 4.8 in
1717

1818
| NuGet | | [![TwitchLib.EventSub.Websockets][1]][2] |
1919
| :--------------- | ----: | :--------------------------------------------------------------------------- |
20-
| Package Manager | `PM>` | `Install-Package TwitchLib.EventSub.Websockets -Version 0.5.0` |
21-
| .NET CLI | `>` | `dotnet add package TwitchLib.EventSub.Websockets --version 0.5.0` |
22-
| PackageReference | | `<PackageReference Include="TwitchLib.EventSub.Websockets" Version="0.5.0" />` |
23-
| Paket CLI | `>` | `paket add TwitchLib.EventSub.Websockets --version 0.5.0` |
20+
| Package Manager | `PM>` | `Install-Package TwitchLib.EventSub.Websockets -Version 0.6.0` |
21+
| .NET CLI | `>` | `dotnet add package TwitchLib.EventSub.Websockets --version 0.6.0` |
22+
| PackageReference | | `<PackageReference Include="TwitchLib.EventSub.Websockets" Version="0.6.0" />` |
23+
| Paket CLI | `>` | `paket add TwitchLib.EventSub.Websockets --version 0.6.0` |
2424

2525
[1]: https://img.shields.io/nuget/v/TwitchLib.EventSub.Websockets.svg?label=TwitchLib.EventSub.Websockets
2626
[2]: https://www.nuget.org/packages/TwitchLib.EventSub.Websockets

TwitchLib.EventSub.Websockets.Example.NetStandard/TwitchLib.EventSub.Websockets.Example.NetStandard.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
<TargetFramework>netframework4.8</TargetFramework>
66
<ImplicitUsings>disable</ImplicitUsings>
77
<Nullable>disable</Nullable>
8+
<LangVersion>latest</LangVersion>
89
</PropertyGroup>
910

1011
<ItemGroup>
1112
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
13+
<PackageReference Include="TwitchLib.Api" Version="3.10.0-preview-4e0146c" />
1214
</ItemGroup>
1315

1416
<ItemGroup>

TwitchLib.EventSub.Websockets.Example.NetStandard/WebsocketHostedService.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Threading;
66
using System.Threading.Tasks;
77
using TwitchLib.Api;
8-
using TwitchLib.Api.Core.Enums;
98
using TwitchLib.EventSub.Websockets.Core.EventArgs;
109
using TwitchLib.EventSub.Websockets.Core.EventArgs.Channel;
1110

@@ -16,7 +15,7 @@ public class WebsocketHostedService : IHostedService
1615
private readonly IConfiguration _configuration;
1716
private readonly ILogger<WebsocketHostedService> _logger;
1817
private readonly EventSubWebsocketClient _eventSubWebsocketClient;
19-
private readonly TwitchApi _twitchApi = new();
18+
private readonly TwitchAPI _twitchApi = new();
2019
private string _userId;
2120

2221
public WebsocketHostedService(IConfiguration configuration ,ILogger<WebsocketHostedService> logger, EventSubWebsocketClient eventSubWebsocketClient)

TwitchLib.EventSub.Websockets.Example.NetStandard/WebsocketHostedServiceWithoutDI.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading.Tasks;
44
using Microsoft.Extensions.Hosting;
55
using Microsoft.Extensions.Logging;
6+
using TwitchLib.Api;
67
using TwitchLib.EventSub.Websockets.Core.EventArgs;
78
using TwitchLib.EventSub.Websockets.Core.EventArgs.Channel;
89

@@ -12,7 +13,7 @@ public class WebsocketHostedServiceWithoutDI : IHostedService
1213
{
1314
private readonly ILogger<WebsocketHostedService> _logger;
1415
private readonly EventSubWebsocketClient _eventSubWebsocketClient;
15-
private readonly TwitchApi _twitchApi = new();
16+
private readonly TwitchAPI _twitchApi = new();
1617
private string _userId;
1718

1819
public WebsocketHostedServiceWithoutDI(ILogger<WebsocketHostedService> logger, ILoggerFactory loggerFactory)

TwitchLib.EventSub.Websockets.Example/TwitchLib.EventSub.Websockets.Example.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
<ItemGroup>
1010
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
11+
<PackageReference Include="TwitchLib.Api" Version="3.10.0-preview-4e0146c" />
1112
</ItemGroup>
1213

1314
<ItemGroup>

TwitchLib.EventSub.Websockets.Example/WebsocketHostedService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class WebsocketHostedService : IHostedService
1515
{
1616
private readonly ILogger<WebsocketHostedService> _logger;
1717
private readonly EventSubWebsocketClient _eventSubWebsocketClient;
18-
private readonly TwitchApi _twitchApi = new();
18+
private readonly TwitchAPI _twitchApi = new();
1919
private string _userId;
2020

2121
public WebsocketHostedService(ILogger<WebsocketHostedService> logger, EventSubWebsocketClient eventSubWebsocketClient)

TwitchLib.EventSub.Websockets/Client/WebsocketClient.cs

Lines changed: 31 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ public class WebsocketClient : IDisposable
2929
/// </summary>
3030
public bool IsFaulted => _webSocket.CloseStatus != WebSocketCloseStatus.Empty && _webSocket.CloseStatus != WebSocketCloseStatus.NormalClosure;
3131

32-
internal event AsyncEventHandler<DataReceivedArgs> OnDataReceived;
33-
internal event AsyncEventHandler<ErrorOccuredArgs> OnErrorOccurred;
32+
internal event AsyncEventHandler<DataReceivedArgs>? OnDataReceived;
33+
internal event AsyncEventHandler<ErrorOccuredArgs>? OnErrorOccurred;
3434

35-
private readonly ClientWebSocket _webSocket;
36-
private readonly ILogger<WebsocketClient> _logger;
35+
private ClientWebSocket _webSocket;
36+
private readonly ILogger<WebsocketClient>? _logger;
3737

3838
/// <summary>
3939
/// Constructor to create a new Websocket client with a logger
4040
/// </summary>
4141
/// <param name="logger">Logger used by the websocket client to print various state info</param>
42-
public WebsocketClient(ILogger<WebsocketClient> logger = null)
42+
public WebsocketClient(ILogger<WebsocketClient>? logger = null)
4343
{
4444
_webSocket = new ClientWebSocket();
4545
_logger = logger;
@@ -56,6 +56,8 @@ public async Task<bool> ConnectAsync(Uri url)
5656
{
5757
if (_webSocket.State is WebSocketState.Open or WebSocketState.Connecting)
5858
return true;
59+
if (_webSocket.State is WebSocketState.Closed) //after a socken is closed it cannot be reopened
60+
_webSocket = new();
5961

6062
await _webSocket.ConnectAsync(url, CancellationToken.None);
6163

@@ -92,66 +94,63 @@ public async Task<bool> DisconnectAsync()
9294
}
9395
}
9496

95-
#if NET6_0_OR_GREATER
9697
/// <summary>
9798
/// Background operation to process incoming data via the websocket
9899
/// </summary>
99100
/// <returns>Task representing the background operation</returns>
100101
/// <exception cref="ArgumentOutOfRangeException"></exception>
101102
private async Task ProcessDataAsync()
102103
{
103-
const int minimumBufferSize = 256;
104-
var storeSize = 4096;
105-
var decoder = Encoding.UTF8.GetDecoder();
106-
107-
var store = MemoryPool<byte>.Shared.Rent(storeSize).Memory;
108-
var buffer = MemoryPool<byte>.Shared.Rent(minimumBufferSize).Memory;
109-
104+
const int bufferLength = 4096;
105+
#if NETSTANDARD2_0
106+
var buffer = new ArraySegment<byte>(new byte[bufferLength]);
107+
#else
108+
var buffer = new Memory<byte>(new byte[bufferLength]);
109+
#endif
110+
var store = new byte[4096];
110111
var payloadSize = 0;
111112

112113
while (IsConnected)
113114
{
114115
try
115116
{
117+
#if NETSTANDARD2_0
118+
WebSocketReceiveResult receiveResult;
119+
#else
116120
ValueWebSocketReceiveResult receiveResult;
121+
#endif
117122
do
118123
{
119124
receiveResult = await _webSocket.ReceiveAsync(buffer, CancellationToken.None);
120-
121-
if (payloadSize + receiveResult.Count >= storeSize)
125+
126+
if (payloadSize + receiveResult.Count >= store.Length)
122127
{
123-
storeSize +=
124-
#if NET8_0_OR_GREATER
125-
int.Max(4096, receiveResult.Count);
126-
#else
127-
Math.Max(4096, receiveResult.Count);
128-
#endif
129-
var newStore = MemoryPool<byte>.Shared.Rent(storeSize).Memory;
130-
store.CopyTo(newStore);
128+
var newStoreLength = store.Length + Math.Max(bufferLength, receiveResult.Count);
129+
var newStore = new byte[newStoreLength];
130+
store.AsSpan().CopyTo(newStore);
131131
store = newStore;
132132
}
133133

134-
buffer.CopyTo(store[payloadSize..]);
134+
buffer
135+
#if NETSTANDARD2_0
136+
.Array.AsSpan(0, receiveResult.Count)
137+
#else
138+
.Span.Slice(0, receiveResult.Count)
139+
#endif
140+
.CopyTo(store.AsSpan(payloadSize));
135141

136142
payloadSize += receiveResult.Count;
137143
} while (!receiveResult.EndOfMessage);
138144

139145
switch (receiveResult.MessageType)
140146
{
141147
case WebSocketMessageType.Text:
142-
{
143-
var intermediate = MemoryPool<char>.Shared.Rent(payloadSize).Memory;
144-
145148
if (payloadSize == 0)
146149
continue;
147150

148-
decoder.Convert(store.Span[..payloadSize], intermediate.Span, true, out _, out var charsCount, out _);
149-
var message = intermediate[..charsCount];
150-
151-
OnDataReceived?.Invoke(this, new DataReceivedArgs { Message = message.Span.ToString() });
151+
OnDataReceived?.Invoke(this, new DataReceivedArgs { Bytes = store.AsSpan(0, payloadSize).ToArray() });
152152
payloadSize = 0;
153153
break;
154-
}
155154
case WebSocketMessageType.Binary:
156155
break;
157156
case WebSocketMessageType.Close:
@@ -168,75 +167,6 @@ private async Task ProcessDataAsync()
168167
}
169168
}
170169
}
171-
#else
172-
/// <summary>
173-
/// Background operation to process incoming data via the websocket
174-
/// </summary>
175-
/// <returns>Task representing the background operation</returns>
176-
/// <exception cref="ArgumentOutOfRangeException"></exception>
177-
private async Task ProcessDataAsync()
178-
{
179-
const int minimumBufferSize = 8192;
180-
181-
var buffer = new ArraySegment<byte>(new byte[minimumBufferSize]);
182-
var payloadSize = 0;
183-
184-
while (IsConnected)
185-
{
186-
try
187-
{
188-
WebSocketReceiveResult receiveResult;
189-
var memory = new MemoryStream();
190-
191-
do
192-
{
193-
receiveResult = await _webSocket.ReceiveAsync(buffer, CancellationToken.None);
194-
195-
if (buffer.Array == null)
196-
continue;
197-
198-
#pragma warning disable CA1849
199-
memory.Write(buffer.Array, buffer.Offset, receiveResult.Count);
200-
#pragma warning restore CA1849
201-
payloadSize += receiveResult.Count;
202-
} while (!receiveResult.EndOfMessage);
203-
204-
switch (receiveResult.MessageType)
205-
{
206-
case WebSocketMessageType.Text:
207-
{
208-
if (payloadSize == 0)
209-
continue;
210-
211-
memory.Seek(0, SeekOrigin.Begin);
212-
213-
var reader = new StreamReader(memory, Encoding.UTF8);
214-
215-
OnDataReceived?.Invoke(this, new DataReceivedArgs { Message = await reader.ReadToEndAsync() });
216-
217-
memory.Dispose();
218-
reader.Dispose();
219-
break;
220-
}
221-
case WebSocketMessageType.Binary:
222-
break;
223-
case WebSocketMessageType.Close:
224-
if (_webSocket.CloseStatus != null)
225-
_logger?.LogWebsocketClosed((WebSocketCloseStatus)_webSocket.CloseStatus!, _webSocket.CloseStatusDescription!);
226-
break;
227-
default:
228-
throw new ArgumentOutOfRangeException();
229-
}
230-
}
231-
232-
catch (Exception ex)
233-
{
234-
OnErrorOccurred?.Invoke(this, new ErrorOccuredArgs { Exception = ex });
235-
break;
236-
}
237-
}
238-
}
239-
#endif
240170

241171
/// <summary>
242172
/// Cleanup of any unused resources as per IDisposable guidelines
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using TwitchLib.EventSub.Core.SubscriptionTypes.Channel;
2+
using TwitchLib.EventSub.Websockets.Core.Models;
3+
4+
namespace TwitchLib.EventSub.Websockets.Core.EventArgs.Channel;
5+
6+
public class ChannelChatClearArgs : TwitchLibEventSubEventArgs<EventSubNotification<ChannelChatClear>>
7+
{ }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using TwitchLib.EventSub.Core.SubscriptionTypes.Channel;
2+
using TwitchLib.EventSub.Websockets.Core.Models;
3+
4+
namespace TwitchLib.EventSub.Websockets.Core.EventArgs.Channel;
5+
6+
public class ChannelChatClearUserMessagesArgs : TwitchLibEventSubEventArgs<EventSubNotification<ChannelChatClearUserMessage>>
7+
{ }

0 commit comments

Comments
 (0)