Skip to content

Commit

Permalink
Add project files.
Browse files Browse the repository at this point in the history
  • Loading branch information
cristipufu committed Feb 4, 2022
1 parent 6a34655 commit 6ceb717
Show file tree
Hide file tree
Showing 8 changed files with 490 additions and 0 deletions.
39 changes: 39 additions & 0 deletions Ninja.WebSocketClient.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ninja.WebSocketClient", "src\Ninja.WebSocketClient\Ninja.WebSocketClient.csproj", "{2E043304-C168-468B-BFD2-26ADE789F399}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{88192113-E622-4F36-B2BB-D60B1E08E853}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{E016B418-F571-4083-9C53-F078FDBDCB9C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ninja.WebSocketClient.DemoConsole", "test\Ninja.WebSocket.DemoConsole\Ninja.WebSocketClient.DemoConsole.csproj", "{ED5FDEEA-BC63-4D6A-8FD4-6F0D226DABFB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2E043304-C168-468B-BFD2-26ADE789F399}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E043304-C168-468B-BFD2-26ADE789F399}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E043304-C168-468B-BFD2-26ADE789F399}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E043304-C168-468B-BFD2-26ADE789F399}.Release|Any CPU.Build.0 = Release|Any CPU
{ED5FDEEA-BC63-4D6A-8FD4-6F0D226DABFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ED5FDEEA-BC63-4D6A-8FD4-6F0D226DABFB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED5FDEEA-BC63-4D6A-8FD4-6F0D226DABFB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED5FDEEA-BC63-4D6A-8FD4-6F0D226DABFB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2E043304-C168-468B-BFD2-26ADE789F399} = {88192113-E622-4F36-B2BB-D60B1E08E853}
{ED5FDEEA-BC63-4D6A-8FD4-6F0D226DABFB} = {E016B418-F571-4083-9C53-F078FDBDCB9C}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D8800A12-B8E6-40AE-9D20-68E2BEFC75F0}
EndGlobalSection
EndGlobal
17 changes: 17 additions & 0 deletions src/Ninja.WebSocketClient/DuplexPipe.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.IO.Pipelines;

namespace Ninja.WebSocketClient
{
internal class DuplexPipe : IDuplexPipe
{
public DuplexPipe(PipeReader reader, PipeWriter writer)
{
Input = reader;
Output = writer;
}

public PipeReader Input { get; }

public PipeWriter Output { get; }
}
}
15 changes: 15 additions & 0 deletions src/Ninja.WebSocketClient/Ninja.WebSocketClient.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Ninja.WebSocketClient</RootNamespace>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.IO.Pipelines" Version="6.0.1" />
</ItemGroup>

</Project>
92 changes: 92 additions & 0 deletions src/Ninja.WebSocketClient/NinjaWebSocket.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System.Buffers;

namespace Ninja.WebSocketClient
{
public class NinjaWebSocket
{
private readonly WebSocketDuplexPipe _webSocketPipe;
private readonly string _url;
private Exception? CloseException { get; set; }

private Task? ReceiveTask { get; set; }

public event Func<Exception?, Task>? Closed;

public event Func<Task>? Connected;

public event Func<ReadOnlySequence<byte>?, Task>? OnReceived;

public NinjaWebSocket(string url)
{
_url = url;
_webSocketPipe = new WebSocketDuplexPipe();
}

public async Task StartAsync(CancellationToken ct = default)
{
await _webSocketPipe.StartAsync(_url, ct);

ReceiveTask = ReceiveLoop();

await (Connected?.Invoke() ?? Task.CompletedTask);
}

public async Task SendAsync(ArraySegment<byte> data, CancellationToken ct = default)
{
await _webSocketPipe.Output.WriteAsync(data, ct);
}

public async Task StopAsync()
{
_webSocketPipe.Input.CancelPendingRead();

await (ReceiveTask ?? Task.CompletedTask);

await _webSocketPipe.StopAsync();
}

private async Task ReceiveLoop()
{
var input = _webSocketPipe.Input;

try
{
while (true)
{
var result = await input.ReadAsync();
var buffer = result.Buffer;

try
{
if (result.IsCanceled)
{
break;
}

if (!buffer.IsEmpty)
{
await (OnReceived?.Invoke(buffer) ?? Task.CompletedTask);
}

if (result.IsCompleted)
{
break;
}
}
finally
{
input.AdvanceTo(buffer.Start, buffer.End);
}
}
}
catch (Exception ex)
{
CloseException = ex;
}
finally
{
await (Closed?.Invoke(CloseException) ?? Task.CompletedTask);
}
}
}
}
Loading

0 comments on commit 6ceb717

Please sign in to comment.