Skip to content

Commit

Permalink
Merge pull request #2 from snowberry-software/develop
Browse files Browse the repository at this point in the history
.NET 9.0
  • Loading branch information
VNNCC authored Nov 14, 2024
2 parents 329f66e + acba960 commit 8d0980a
Show file tree
Hide file tree
Showing 13 changed files with 65 additions and 83 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.x
7.x
8.x
9.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand All @@ -41,12 +42,13 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
6.x
7.x
8.x
9.x
- name: Restore dependencies
run: dotnet restore
- name: Build
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ serverPipe.GotConnectionEvent += (sender, e) =>
Console.WriteLine("Server pipe got a new client...");
};

serverPipe.PipeClosed += (_, _) =>
serverPipe.PipeClosed += (_, reason) =>
{
Console.WriteLine("Server pipe got closed...");
Console.WriteLine("Server pipe got closed ({0})...", reason);
};

await serverPipe.WaitForClientAsync();
Expand All @@ -57,9 +57,9 @@ clientPipe.DataReceived += (s, e) =>
Console.ResetColor();
};

clientPipe.PipeClosed += (_, _) =>
clientPipe.PipeClosed += (_, reason) =>
{
Console.WriteLine("Server pipe got closed...");
Console.WriteLine("Client pipe got closed ({0})...", reason);
};

await clientPipe.ConnectAsync();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Text;
using Snowberry.IPC;
using Snowberry.IPC.NamedPipes;

Console.Title = "Example Client";

Expand All @@ -15,9 +15,9 @@
Console.ResetColor();
};

clientPipe.PipeClosed += (_, _) =>
clientPipe.PipeClosed += (_, reason) =>
{
Console.WriteLine("Server pipe got closed...");
Console.WriteLine("Client pipe got closed ({0})...", reason);
};

Console.WriteLine("Waiting for server connection...");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using System.Text;
using Snowberry.IPC;
using Snowberry.IPC.NamedPipes;

Console.Title = "Example Server";

Expand All @@ -22,9 +22,9 @@
Console.WriteLine("Server pipe got a new client...");
};

serverPipe.PipeClosed += (_, _) =>
serverPipe.PipeClosed += (_, reason) =>
{
Console.WriteLine("Server pipe got closed...");
Console.WriteLine("Server pipe got closed ({0})...", reason);
};

Console.WriteLine("Waiting for client to connect...");
Expand Down
11 changes: 7 additions & 4 deletions src/Snowberry.IPC.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Snowberry.IPC", "Snowberry.
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Examples", "Examples", "{B8188513-3BDC-4E24-8B83-53792732C84E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExampleServer", "ExampleServer\ExampleServer.csproj", "{4C237A91-414B-43A5-B2D6-833493C053EF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.Pipe.Server", "Example.Pipe.Server\Example.Pipe.Server.csproj", "{4C237A91-414B-43A5-B2D6-833493C053EF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExampleClient", "ExampleClient\ExampleClient.csproj", "{2E6D9C70-39EA-4153-B9C7-FD9FCEC72C98}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Example.Pipe.Client", "Example.Pipe.Client\Example.Pipe.Client.csproj", "{2E6D9C70-39EA-4153-B9C7-FD9FCEC72C98}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1BC16FF6-E494-4016-AF17-45340282E3D6}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NamedPipes", "NamedPipes", "{3C3D419D-D8C4-4DCA-91EB-65B3B7308AF2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -39,8 +41,9 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4C237A91-414B-43A5-B2D6-833493C053EF} = {B8188513-3BDC-4E24-8B83-53792732C84E}
{2E6D9C70-39EA-4153-B9C7-FD9FCEC72C98} = {B8188513-3BDC-4E24-8B83-53792732C84E}
{4C237A91-414B-43A5-B2D6-833493C053EF} = {3C3D419D-D8C4-4DCA-91EB-65B3B7308AF2}
{2E6D9C70-39EA-4153-B9C7-FD9FCEC72C98} = {3C3D419D-D8C4-4DCA-91EB-65B3B7308AF2}
{3C3D419D-D8C4-4DCA-91EB-65B3B7308AF2} = {B8188513-3BDC-4E24-8B83-53792732C84E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BD4E5933-FE40-41DB-891B-ED7F52C1A84E}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipes;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Snowberry.IPC.Events;

namespace Snowberry.IPC;
using Snowberry.IPC.NamedPipes.Events;

namespace Snowberry.IPC.NamedPipes;

/// <summary>
/// The base type for the pipe server and client.
Expand All @@ -24,26 +24,31 @@ public abstract class BasePipe : IDisposable
/// <summary>
/// Gets called when the pipe gets closed by losing the connection between the client and the server.
/// </summary>
public event EventHandler? PipeClosed;
public event EventHandler<PipeCloseReason>? PipeClosed;

protected readonly string? _pipeDebugName;
protected PipeStream? _pipeStream;
protected bool _protectedIsConnected;

protected List<byte> _dynamicPacketBuffer = [];
protected bool _useDynamicDataPacketSize;

public BasePipe(string? pipeDebugName, PipeStream pipeStream) : this(pipeDebugName, pipeStream, false)
{
}

public BasePipe(string? pipeDebugName, PipeStream pipeStream, bool useDynamicDataPacketSize)
/// <summary>
/// Creates a new base pipe.
/// </summary>
/// <param name="pipeDebugName">The optional debug name.</param>
/// <param name="pipeStream">The stream of the pipe.</param>
/// <param name="useDynamicDataPacketSize">Whether to use <see cref="UseDynamicDataPacketSize"/>.</param>
public BasePipe(string? pipeDebugName, PipeStream pipeStream, bool useDynamicDataPacketSize = false)
{
_pipeDebugName = pipeDebugName;
_pipeStream = pipeStream ?? throw new ArgumentNullException(nameof(pipeStream));
_useDynamicDataPacketSize = useDynamicDataPacketSize;
}

/// <summary>
/// Creates a new base pipe.
/// </summary>
/// <param name="pipeDebugName">The optional debug name</param>
protected BasePipe(string? pipeDebugName)
{
_pipeDebugName = pipeDebugName;
Expand All @@ -52,7 +57,7 @@ protected BasePipe(string? pipeDebugName)
/// <summary>
/// Gets called when the pipe stream has been initialized.
/// </summary>
protected abstract void OnPipeStreamInitialized();
protected abstract void OnPipeStreamCreated();

/// <summary>
/// Gets called when the pipe closes.
Expand Down Expand Up @@ -91,9 +96,6 @@ public async Task StartReadingAsync(CancellationToken token)

byte[] buffer = new byte[MaxBufferLength];

if (EnableDebugLogs)
Console.WriteLine($"{_pipeDebugName}: Start reading...");

if (!UseDynamicDataPacketSize)
{
await HandleStaticBufferAsync(buffer, token);
Expand All @@ -105,31 +107,25 @@ public async Task StartReadingAsync(CancellationToken token)

protected virtual async Task HandleStaticBufferAsync(byte[] buffer, CancellationToken token)
{
if (EnableDebugLogs)
Console.WriteLine($"{_pipeDebugName}: Reading statically...");

#if NET6_0_OR_GREATER
int readLength = await _pipeStream!.ReadAsync(buffer.AsMemory(0, MaxBufferLength), token);
#else
int readLength = await _pipeStream!.ReadAsync(buffer, 0, MaxBufferLength, token);
#endif

if (EnableDebugLogs)
Console.WriteLine($"{_pipeDebugName}: Statically read {readLength} bytes...");

if (IsPipeClosed(readLength, token))
return;

OnDataReceived(buffer, readLength);
DataReceived?.Invoke(this, new PipeEventArgs(buffer, readLength, usedDynamicallyRead: false));
byte[] readBytes = new byte[readLength];
Array.Copy(buffer, readBytes, readLength);

OnDataReceived(readBytes, readLength);
DataReceived?.Invoke(this, new PipeEventArgs(readBytes, readLength, usedDynamicallyRead: false));
await StartReadingAsync(token);
}

protected virtual async Task HandleDynamicBufferAsync(byte[] buffer, CancellationToken token)
{
if (EnableDebugLogs)
Console.WriteLine($"{_pipeDebugName}: Reading dynamically...");

int expectedRead = -1;
var dynamicBuffer = new List<byte>();
do
Expand All @@ -140,17 +136,14 @@ protected virtual async Task HandleDynamicBufferAsync(byte[] buffer, Cancellatio
int readLength = await _pipeStream!.ReadAsync(buffer, 0, MaxBufferLength, token);
#endif

if (EnableDebugLogs)
Console.WriteLine($"{_pipeDebugName}: Dynamically read {readLength} bytes...");

if (IsPipeClosed(readLength, token))
return;

if (expectedRead == -1)
{
expectedRead = BitConverter.ToInt32(buffer, 0);

if ((readLength - 4) == expectedRead)
if (readLength - 4 == expectedRead)
{
#if NET6_0_OR_GREATER
byte[] actualBuffer = buffer.AsSpan()[4..readLength].ToArray();
Expand All @@ -163,8 +156,6 @@ protected virtual async Task HandleDynamicBufferAsync(byte[] buffer, Cancellatio
await StartReadingAsync(token);
return;
}

continue;
}

dynamicBuffer.AddRange(buffer.Take(readLength));
Expand All @@ -184,7 +175,7 @@ protected virtual bool IsPipeClosed(int readLength, CancellationToken token)

_protectedIsConnected = false;
OnPipeClosed(PipeCloseReason.NoConnection);
PipeClosed?.Invoke(this, EventArgs.Empty);
PipeClosed?.Invoke(this, PipeCloseReason.NoConnection);
return true;
}

Expand All @@ -198,14 +189,8 @@ public virtual Task WriteAsync(byte[] data, int offset, int length)
{
_ = _pipeStream ?? throw new NullReferenceException(nameof(_pipeStream));

if (EnableDebugLogs)
Console.WriteLine($"{_pipeDebugName}: Writing {length} bytes...");

if (UseDynamicDataPacketSize)
{
if (EnableDebugLogs)
Console.WriteLine($"\t> Using dynamic write...");

#if NET6_0_OR_GREATER
var packet = new List<byte>(data.AsSpan().Slice(offset, length).ToArray());
#else
Expand Down Expand Up @@ -243,15 +228,14 @@ public virtual void Dispose()
return;

if (_pipeStream.IsConnected)
{
#if NET6_0_OR_GREATER
if (OperatingSystem.IsWindows())
#endif
_pipeStream.WaitForPipeDrain();
}

_pipeStream.Close();
OnPipeClosed(PipeCloseReason.Dispose);
PipeClosed?.Invoke(this, PipeCloseReason.Dispose);
_pipeStream.Dispose();
_pipeStream = null!;
}
Expand All @@ -262,7 +246,7 @@ public virtual void Dispose()
public string? PipeDebugName => _pipeDebugName;

/// <summary>
/// Determines wheter the pipe stream is connected.
/// Determines whether the pipe stream is connected.
/// </summary>
public bool IsConnected =>
// NOTE(VNC):
Expand All @@ -278,18 +262,14 @@ public virtual void Dispose()
/// <remarks>
/// The length of the data will be written as 32bit-integer before the payload if this is enabled.<para/>
/// The read operation will only be completed if the data length is exactly as the length that has been provided.<para/>
/// If this is disabled and the incoming payload is longer than <see cref="MaxBufferLength"/> then it will be split to two different read cycles.<para/>
/// </remarks>
public bool UseDynamicDataPacketSize
{
get => _useDynamicDataPacketSize;
set => _useDynamicDataPacketSize = value;
}

/// <summary>
/// Enables debug loggin.
/// </summary>
public bool EnableDebugLogs { get; set; }

/// <summary>
/// The pipe stream that is used.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using System.IO.Pipes;
using System.Threading.Tasks;

namespace Snowberry.IPC;
namespace Snowberry.IPC.NamedPipes;

/// <summary>
/// The client pipe type.
Expand All @@ -12,11 +12,11 @@ public class ClientPipe : BasePipe
public ClientPipe(string serverName, string pipeName, string? pipeDebugName) : base(pipeDebugName)
{
_pipeStream = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous);
OnPipeStreamInitialized();
OnPipeStreamCreated();
}

/// <inheritdoc/>
protected override void OnPipeStreamInitialized()
protected override void OnPipeStreamCreated()
{
}

Expand All @@ -32,7 +32,6 @@ public async Task<bool> ConnectAsync(int? timeout = null)
if (timeout == null)
await ((NamedPipeClientStream)_pipeStream).ConnectAsync();
else
{
try
{
await ((NamedPipeClientStream)_pipeStream).ConnectAsync(timeout.Value);
Expand All @@ -41,7 +40,6 @@ public async Task<bool> ConnectAsync(int? timeout = null)
{
return false;
}
}

if (_pipeStream.IsConnected)
{
Expand Down
Loading

0 comments on commit 8d0980a

Please sign in to comment.