https://github.com/devlooped/websocketchannel
High-performance System.Threading.Channels API adapter for System.Net.WebSockets
https://github.com/devlooped/websocketchannel
csharp dotnet websocket websockets
Last synced: 3 months ago
JSON representation
High-performance System.Threading.Channels API adapter for System.Net.WebSockets
- Host: GitHub
- URL: https://github.com/devlooped/websocketchannel
- Owner: devlooped
- License: mit
- Created: 2021-10-04T16:25:00.000Z (almost 4 years ago)
- Default Branch: main
- Last Pushed: 2025-03-18T00:28:44.000Z (4 months ago)
- Last Synced: 2025-03-25T03:34:03.654Z (4 months ago)
- Topics: csharp, dotnet, websocket, websockets
- Language: C#
- Homepage: https://clarius.org/WebSocketChannel
- Size: 169 KB
- Stars: 11
- Watchers: 2
- Forks: 3
- Open Issues: 7
-
Metadata Files:
- Readme: readme.md
- Changelog: changelog.md
- License: license.txt
Awesome Lists containing this project
README
 WebSocketChannel
============High-performance [System.Threading.Channels](https://devblogs.microsoft.com/dotnet/an-introduction-to-system-threading-channels/) API adapter for System.Net.WebSockets
[](https://www.nuget.org/packages/WebSocketChannel)
[](https://www.nuget.org/packages/WebSocketChannel)
[](https://github.com/devlooped/WebSocketChannel/blob/main/license.txt)
[](https://github.com/devlooped/WebSocketChannel/actions)# Usage
```csharp
var client = new ClientWebSocket();
await client.ConnectAsync(serverUri, CancellationToken.None);Channel> channel = client.CreateChannel();
await channel.Writer.WriteAsync(Encoding.UTF8.GetBytes("hello").AsMemory());
// Read single message when it arrives
ReadOnlyMemory response = await channel.Reader.ReadAsync();// Read all messages while underlying websocket is open
await foreach (var item in channel.Reader.ReadAllAsync())
{
Console.WriteLine(Encoding.UTF8.GetString(item.Span));
}// Completing the writer closes the underlying websocket cleanly
channel.Writer.Complete();// Can also complete reporting an error for the remote party
channel.Writer.Complete(new InvalidOperationException("Bad format"));
```The `WebSocketChannel` can also be used on the server. The following example is basically
taken from the documentation on [WebSockets in ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/websockets?view=aspnetcore-5.0#configure-the-middleware)
and adapted to use a `WebSocketChannel` to echo messages to the client:```csharp
app.Use(async (context, next) =>
{
if (context.Request.Path == "/ws")
{
if (context.WebSockets.IsWebSocketRequest)
{
using var webSocket = await context.WebSockets.AcceptWebSocketAsync();
var channel = WebSocketChannel.Create(webSocket);
try
{
await foreach (var item in channel.Reader.ReadAllAsync(context.RequestAborted))
{
await channel.Writer.WriteAsync(item, context.RequestAborted);
}
}
catch (OperationCanceledException)
{
try
{
await webSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, default);
}
catch { } // Best effort to try closing cleanly. Client may be entirely gone.
}
}
else
{
context.Response.StatusCode = (int) HttpStatusCode.BadRequest;
}
}
else
{
await next();
}
});
```# Installation
This project can be used either as a regular nuget package:
```
```
Or alternatively, referenced directly as a source-only dependency using [dotnet-file](https://www.nuget.org/packages/dotnet-file):
```
> dotnet file add https://github.com/devlooped/WebSocketChannel/blob/main/src/WebSocketChannel/WebSocketChannel.cs
> dotnet file add https://github.com/devlooped/WebSocketChannel/blob/main/src/WebSocketChannel/WebSocketExtensions.cs
```It's also possible to specify a desired target location for the referenced source files, such as:
```
> dotnet file add https://github.com/devlooped/WebSocketChannel/blob/main/src/WebSocketChannel/WebSocketChannel.cs src/MyProject/External/.
> dotnet file add https://github.com/devlooped/WebSocketChannel/blob/main/src/WebSocketChannel/WebSocketExtensions.cs src/MyProject/External/.
```When referenced as loose source files, it's easy to also get automated PRs when the upstream files change,
as in the [dotnet-file.yml](https://github.com/devlooped/dotnet-file/blob/main/.github/workflows/dotnet-file.yml) workflow that
keeps the repository up to date with a template. See also [dotnet-config](https://dotnetconfig.org), which is used to
for the `dotnet-file` configuration settings that tracks all this.# Dogfooding
[](https://pkg.kzu.io/index.json)
[](https://github.com/devlooped/WebSocketChannel/actions)We also produce CI packages from branches and pull requests so you can dogfood builds as quickly as they are produced.
The CI feed is `https://pkg.kzu.io/index.json`.
The versioning scheme for packages is:
- PR builds: *42.42.42-pr*`[NUMBER]`
- Branch builds: *42.42.42-*`[BRANCH]`.`[COMMITS]`# Sponsors
[](https://github.com/clarius)
[](https://github.com/augustoproiete)
[](https://github.com/KirillOsenkov)
[](https://github.com/MFB-Technologies-Inc)
[](https://github.com/decriptor)
[](https://github.com/torutek-gh)
[](https://github.com/drivenet)
[](https://github.com/davkean)
[](https://github.com/chiluap)
[](https://github.com/dgnaegi)
[](https://github.com/AshleyMedway)
[](https://github.com/Keflon)
[](https://github.com/bitbonk)
[](https://github.com/tbolon)
[](https://github.com/yrashk)
[](https://github.com/kfrancis)
[](https://github.com/wdolek)
[](https://github.com/SeanKilleen)
[](https://github.com/twenzel)
[](https://github.com/Giorgi)
[](https://github.com/mckhendry)
[](https://github.com/aritchie)
[](https://github.com/MikeCodesDotNET)
[](https://github.com/unoplatform)
[](https://github.com/dansiegel)
[](https://github.com/rbnswartz)
[](https://github.com/jeremysimmons)
[](https://github.com/jfoshee)
[](https://github.com/Mrxx99)
[](https://github.com/eajhnsn1)
[](https://github.com/mackayn)
[](https://github.com/certifytheweb)
[](https://github.com/lavahot)
[](https://github.com/mrange)
[](https://github.com/davidpetric)
[](https://github.com/richlee)
[](https://github.com/dannevesdantas)
[](https://github.com/nietras)
[](https://github.com/garywoodfine)
[](https://github.com/kristinnstefansson)
[](https://github.com/DarrenAtConexus)
[](https://github.com/kazo0)
[](https://github.com/IxTechnologies)
[](https://github.com/newrelic)
[](https://github.com/Chris-Johnston)
[](https://github.com/davidjenni)
[](https://github.com/ehonda)
[](https://github.com/Jonathan-Hickey)
[](https://github.com/okyrylchuk)[](https://github.com/sponsors/devlooped)
[Learn more about GitHub Sponsors](https://github.com/sponsors)