Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/NATS.Client.Abstractions/INatsSocketConnection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Net.Sockets;

namespace NATS.Client.Core;

/// <summary>
/// Represents a socket connection to a NATS server.
/// </summary>
/// <remarks>
/// This interface defines the contract for low-level socket connections to NATS servers,
/// providing methods for sending and receiving data and disposing the socket.
/// Disposing should attempt to perform graceful shutdown of the socket.
/// </remarks>
public interface INatsSocketConnection : IAsyncDisposable
{
/// <summary>
/// Sends data asynchronously over the connection.
/// </summary>
/// <param name="buffer">The buffer containing the data to send.</param>
/// <returns>A task representing the asynchronous send operation with the number of bytes sent.</returns>
ValueTask<int> SendAsync(ReadOnlyMemory<byte> buffer);

/// <summary>
/// Receives data asynchronously from the connection.
/// </summary>
/// <param name="buffer">The buffer to store the received data.</param>
/// <returns>A task representing the asynchronous receive operation with the number of bytes received.</returns>
ValueTask<int> ReceiveAsync(Memory<byte> buffer);
}

/// <summary>
/// Represents a NATS socket connection that can be upgraded to use TLS.
/// </summary>
/// <remarks>
/// This interface extends <see cref="INatsSocketConnection"/> to provide access to the underlying
/// socket that is used to create a SslStream.
/// </remarks>
public interface INatsTlsUpgradeableSocketConnection : INatsSocketConnection
{
/// <summary>
/// Gets the underlying Socket instance for the connection.
/// </summary>
Socket Socket { get; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
<PackageReference Include="System.Memory" Version="4.5.5"/>
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0"/>
</ItemGroup>

</Project>
42 changes: 0 additions & 42 deletions src/NATS.Client.Core/INatsSocketConnection.cs
Original file line number Diff line number Diff line change
@@ -1,32 +1,5 @@
using System.Net.Sockets;

namespace NATS.Client.Core;

/// <summary>
/// Represents a socket connection to a NATS server.
/// </summary>
/// <remarks>
/// This interface defines the contract for low-level socket connections to NATS servers,
/// providing methods for sending and receiving data and disposing the socket.
/// Disposing should attempt to perform graceful shutdown of the socket.
/// </remarks>
public interface INatsSocketConnection : IAsyncDisposable
{
/// <summary>
/// Sends data asynchronously over the connection.
/// </summary>
/// <param name="buffer">The buffer containing the data to send.</param>
/// <returns>A task representing the asynchronous send operation with the number of bytes sent.</returns>
ValueTask<int> SendAsync(ReadOnlyMemory<byte> buffer);

/// <summary>
/// Receives data asynchronously from the connection.
/// </summary>
/// <param name="buffer">The buffer to store the received data.</param>
/// <returns>A task representing the asynchronous receive operation with the number of bytes received.</returns>
ValueTask<int> ReceiveAsync(Memory<byte> buffer);
}

/// <summary>
/// Obsolete, use <see cref="INatsSocketConnection"/> instead
/// </summary>
Expand All @@ -39,18 +12,3 @@ public interface ISocketConnection : INatsSocketConnection

ValueTask AbortConnectionAsync(CancellationToken cancellationToken);
}

/// <summary>
/// Represents a NATS socket connection that can be upgraded to use TLS.
/// </summary>
/// <remarks>
/// This interface extends <see cref="INatsSocketConnection"/> to provide access to the underlying
/// socket that is used to create a SslStream.
/// </remarks>
public interface INatsTlsUpgradeableSocketConnection : INatsSocketConnection
{
/// <summary>
/// Gets the underlying Socket instance for the connection.
/// </summary>
Socket Socket { get; }
}
2 changes: 2 additions & 0 deletions src/NATS.Client.Core/TypeForwarders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
[assembly: TypeForwardedTo(typeof(INatsSerialize<>))]
[assembly: TypeForwardedTo(typeof(INatsDeserialize<>))]
[assembly: TypeForwardedTo(typeof(INatsSerializerRegistry))]
[assembly: TypeForwardedTo(typeof(INatsSocketConnection))]
[assembly: TypeForwardedTo(typeof(INatsTlsUpgradeableSocketConnection))]
14 changes: 14 additions & 0 deletions tests/NATS.Client.CheckAbi/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
Check("INatsSerializeWithContext<>", "NATS.Client.Abstractions", typeof(INatsSerializeWithContext<>).Assembly.GetName().Name!);
Check("INatsDeserializeWithContext<>", "NATS.Client.Abstractions", typeof(INatsDeserializeWithContext<>).Assembly.GetName().Name!);
Check("NatsMsgContext", "NATS.Client.Abstractions", typeof(NatsMsgContext).Assembly.GetName().Name!);
Check("INatsSocketConnection", "NATS.Client.Abstractions", typeof(INatsSocketConnection).Assembly.GetName().Name!);
Check("INatsTlsUpgradeableSocketConnection", "NATS.Client.Abstractions", typeof(INatsTlsUpgradeableSocketConnection).Assembly.GetName().Name!);
Console.WriteLine();

Console.WriteLine("Types as seen by TransientLib (compiled against 2.6.0):");
Check("INatsSerialize<> (transient)", "NATS.Client.Abstractions", MySerializer.GetSerializerInterfaceAssembly());
Check("INatsSocketConnection (transient)", "NATS.Client.Abstractions", MySocketConnection.GetSocketConnectionInterfaceAssembly());
Check("INatsTlsUpgradeableSocketConnection (transient)", "NATS.Client.Abstractions", MySocketConnection.GetTlsUpgradeableInterfaceAssembly());
Console.WriteLine();

Console.WriteLine("Assembly versions at runtime:");
Expand Down Expand Up @@ -54,6 +58,16 @@

Console.WriteLine();

Console.WriteLine("Testing TransientLib.MySocketConnection (compiled against 2.6.0):");
INatsSocketConnection connection = new MySocketConnection();

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.11)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.11)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.11)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.11)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.11)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.11)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (main)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (main)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (main)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (main)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (main)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (main)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.12)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.12)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.12)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.12)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.12)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (v2.12)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (latest)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (latest)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (latest)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (latest)

Cannot implicitly convert type 'NATS.Client.CheckAbiTransientLib.MySocketConnection' to 'NATS.Client.Core.INatsSocketConnection'. An explicit conversion exists (are you missing a cast?)

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (latest)

Reference to type 'INatsSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found

Check failure on line 62 in tests/NATS.Client.CheckAbi/Program.cs

View workflow job for this annotation

GitHub Actions / Linux (latest)

Reference to type 'INatsTlsUpgradeableSocketConnection' claims it is defined in 'NATS.Client.Core', but it could not be found
var sent = await connection.SendAsync(new ReadOnlyMemory<byte>(new byte[7]));
Console.WriteLine($" SendAsync reported {sent} bytes");
if (sent != 7)
errors.Add($"SendAsync failed: got {sent}");
await connection.DisposeAsync();

Console.WriteLine();

if (errors.Count > 0)
{
Console.Error.WriteLine($"FAILED: {errors.Count} error(s):");
Expand Down
30 changes: 30 additions & 0 deletions tests/NATS.Client.CheckAbiTransientLib/MySocketConnection.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System.Net.Sockets;
using NATS.Client.Core;

namespace NATS.Client.CheckAbiTransientLib;

/// <summary>
/// Compiled against NATS.Net 2.6.0 where INatsSocketConnection and
/// INatsTlsUpgradeableSocketConnection live in NATS.Client.Core. When used with a newer
/// build, type forwarding should redirect both to NATS.Client.Abstractions.
/// </summary>
public class MySocketConnection : INatsTlsUpgradeableSocketConnection
{
public Socket Socket => throw new NotSupportedException();

public static string GetSocketConnectionInterfaceAssembly()
{
return typeof(INatsSocketConnection).Assembly.GetName().Name!;
}

public static string GetTlsUpgradeableInterfaceAssembly()
{
return typeof(INatsTlsUpgradeableSocketConnection).Assembly.GetName().Name!;
}

public ValueTask<int> SendAsync(ReadOnlyMemory<byte> buffer) => new(buffer.Length);

public ValueTask<int> ReceiveAsync(Memory<byte> buffer) => new(0);

public ValueTask DisposeAsync() => default;
}
Loading