Netsphere 0.51.2
dotnet add package Netsphere --version 0.51.2
NuGet\Install-Package Netsphere -Version 0.51.2
<PackageReference Include="Netsphere" Version="0.51.2" />
<PackageVersion Include="Netsphere" Version="0.51.2" />
<PackageReference Include="Netsphere" />
paket add Netsphere --version 0.51.2
#r "nuget: Netsphere, 0.51.2"
#:package Netsphere@0.51.2
#addin nuget:?package=Netsphere&version=0.51.2
#tool nuget:?package=Netsphere&version=0.51.2
Netsphere is a network library for C#
Netsphere is a transport protocol based on UDP.
Very versatile and easy to use.
Covers a wide range of network needs.
Full serialization features integrated with Tinyhand.
Table of Contents
- Requirements
- Quick Start
- Instance management
- Adding NetService
- Checklist for NetService
- ResponseChannel
Requirements
Visual Studio 2026 or later for Source Generator V2.
C# 14 or later for generated codes.
.NET 10 or later target framework.
Quick start
Install Netsphere using Package Manager Console.
Install-Package Netsphere
This is a small example code to use Netsphere.
First, define an interface shared between the client and server.
[NetService] // Annotate NetService attribute.
public interface ITestService : INetService // NetService must inherit from INetService.
{
Task<string?> DoubleString(string input); // Declare the service method.
// Ensure that both arguments and return values are serializable by Tinyhand serializer, and the return type must be Task or Task<T> or Task or Task<TResult>.
Task<int> Sum(int x, int y); // Calculates the sum of two integers.
Task<NetResultAndValue<int>> Random(); // Gets a random integer value wrapped in a <see cref="NetResultAndValue{T}"/>.
Task<NetResult> Disable(); // Disables the service.
}
On the client side:
Create an instance, connect to the server, obtain the service interface, and call the function.
var unit = builder.Build(); // Create a NetUnit unit that implements communication functionality.
await unit.Run(new NetOptions(), true); // Execute the created unit with default options.
var netUnit = unit.Context.ServiceProvider.GetRequiredService<NetUnit>(); // Get a NetUnit instance.
// using (var connection = await netUnit.NetTerminal.UnsafeConnect(new(IPAddress.Loopback, 1981)))
var netNode = NetNode.Loopback(1981, "(e:XWLus_KiQ3AaNVeBDBp3qaot8wQEbmzlHD3Wkg8cWmXZ5egP)");
using (var connection = await netUnit.NetTerminal.Connect(netNode!))
{// Connect to the server's address (loopback address).
// All communication in Netsphere is encrypted, and connecting by specifying only the address is not recommended due to the risk of man-in-the-middle attacks.
if (connection is null)
{
await Console.Out.WriteLineAsync("No connection");
}
else
{
var service = connection.GetService<ITestService>(); // Retrieve an instance of the target service.
var input = "Nupo";
var output = await service.DoubleString(input); // Arguments are sent to the server through the Tinyhand serializer, processed, and the results are received.
await Console.Out.WriteLineAsync($"{input} -> {output}");
var sum = await service.Sum(1, 2); // // Get the sum of 1 and 2, but it is not implemented on the server side.
await Console.Out.WriteLineAsync($"1 + 2 = {sum}"); // 0
var result = await service.Random();
await Console.Out.WriteLineAsync($"{result}");
await service.Disable();
result = await service.Random();
await Console.Out.WriteLineAsync($"{result}");
}
}
await unit.Terminate(); // Perform the termination process for the unit.
On the server side:
Define a class that implements the interface and annotate it with NetObject attribute.
[NetObject] // Annotate NetObject attribute.
internal class TestServiceAgent : ITestService
{
private readonly int number = RandomVault.Default.NextInt31();
async Task<string?> ITestService.DoubleString(string input)
=> input + input;
async Task<int> ITestService.Sum(int x, int y)
=> x + y;
Task<NetResultAndValue<int>> ITestService.Random()
=> Task.FromResult(new NetResultAndValue<int>(this.number));
async Task<NetResult> ITestService.Disable()
{
TransmissionContext.Current.ServerConnection.GetContext().DisableNetService<ITestService>();
return NetResult.Success;
}
}
Create a builder to instantiate, register Options and Services. From the builder, you create a Unit and execute it.
// Create a NetUnit builder.
var builder = new NetUnit.Builder()
.Configure(context =>
{
})
.PostConfigure(context =>
{
context.SetOptions(context.GetOptions<NetOptions>() with
{
NodeName = "Test server",
Port = 1981, // Specify the port number.
NodeSecretKey = "!!!m6Ao8Rkgsrn1-EqG_kzZgrKmWXt5orPpHAz6DbSaAfUmlLCN!!!(e:XWLus_KiQ3AaNVeBDBp3qaot8wQEbmzlHD3Wkg8cWmXZ5egP)", // Test Private key.
EnablePing = true,
EnableServer = true,
});
});
var unit = builder.Build(); // Create a unit that provides network functionality.
var options = unit.Context.ServiceProvider.GetRequiredService<NetOptions>();
await unit.Run(options, true); // Execute the created unit with the specified options.
await Console.Out.WriteLineAsync(options.ToString()); // Display the NetOptions.
var netBase = unit.Context.ServiceProvider.GetRequiredService<NetBase>();
var node = new NetNode(new(IPAddress.Loopback, (ushort)options.Port), netBase.NodePublicKey);
// Specify which NetService should be enabled by default when a client connects.
var netTerminal = unit.Context.ServiceProvider.GetRequiredService<NetTerminal>();
netTerminal.Services.EnableNetService<ITestService>();
await Console.Out.WriteLineAsync($"{options.NodeName}: {node.ToString()}");
await Console.Out.WriteLineAsync("Ctrl+C to exit");
await ThreadCore.Root.Delay(Timeout.InfiniteTimeSpan); // Wait until the server shuts down.
await unit.Terminate(); // Perform the termination process for the unit.
Instance management
- Service object: An instance is created for each connection by the DI container.
- Service filter: Generated for each agent type (not for each instance).
Adding NetService
NetService is the core functionality of Netsphere and is designed to be as easy to use as possible. However, due to its nature, several steps are required when using it:
Define the interface shared between the client and server.
[NetService] public interface ITestService : INetService { Task<string?> DoubleString(string input); }Implement the NetService agent (implementation class) on the server side.
[NetObject] internal class TestServiceAgent : ITestService { async Task<string?> ITestService.DoubleString(string input) => input + input; }Specify which NetService should be enabled by default when a client connects.
var netTerminal = unit.Context.ServiceProvider.GetRequiredService<NetTerminal>(); netTerminal.Services.EnableNetService<ITestService>();You can also disable or enable the NetService on the server side.
async Task<NetResult> ITestService.Disable() { TransmissionContext.Current.ServerConnection.GetContext().DisableNetService<ITestService>(); return NetResult.Success; }
Checklist for NetService
Check whether the service object can be created by the DI container.
Check whether the NetService is enabled via
NetTerminal.Services.
ResponseChannel
Normally, you define NetService methods that return Task to communicate between the client and server.
Only when the server-side processing is simple and does not require asynchronous work, you can use methods that take a ResponseChannel (delegate).
[NetService]
public interface IServiceA : INetService
{
Task<int> MethodA(int x, int y); // A standard method that uses Task.
void MethodB(int x, int y, ref ResponseChannel<int> channel); // A method that uses ResponseChannel.
}
The characteristics are as follows:
- The method return type is void. You can have multiple parameters, but the last parameter must be
ref ResponseChannel<TResponse>. ResponseChannel<TResponse>is used on the client side to specify the post-receive handler (delegate), and on the server side to specify the return value.- Pay special attention to the fact that a ref parameter is required.
Below is an implementation example.
[NetObject]
public class ServiceAImpl : IServiceA
{
public async Task<int> MethodA(int x, int y)
=> x + y;
public void MethodB(int x, int y, ref ResponseChannel<int> channel)
=> channel.SetResponse(x + y); // Set the return value via the channel.
}
public static class ExampleA
{
public static async Task ServiceA(ClientConnection clientConnection)
{
var service = clientConnection.GetService<IServiceA>();
var result = await service.MethodA(1, 2); // 1 + 2 = 3
// First, create a ResponseChannel(delegate) to handle the response from the server.
var channel = new ResponseChannel<int>((result, value) => { Console.WriteLine(value); });
// Call the method that takes a ResponseChannel as its last argument.
service.MethodB(1, 2, ref channel);
// Wait until receiving is complete. The delegate described above will be invoked while this method is running.
await clientConnection.WaitForReceiveCompletion();
}
}
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Arc.Collections (>= 1.33.0)
- Arc.CrossChannel (>= 2.10.2)
- Arc.Crypto (>= 1.42.1)
- Arc.Threading (>= 0.36.2)
- Arc.Unit (>= 0.37.0)
- BigMachines (>= 0.53.3)
- Microsoft.Extensions.DependencyInjection (>= 10.0.5)
- SimpleCommandLine (>= 0.39.3)
- Tinyhand (>= 0.135.3)
- ValueLink (>= 0.109.2)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on Netsphere:
| Package | Downloads |
|---|---|
|
Netsphere.Shared
Netsphere.Shared |
|
|
Lp
Lp is an experimental program that create value. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.51.2 | 92 | 3/31/2026 |
| 0.51.1 | 80 | 3/31/2026 |
| 0.51.0 | 87 | 3/30/2026 |
| 0.50.0 | 187 | 3/28/2026 |
| 0.49.0 | 123 | 3/16/2026 |
| 0.48.2 | 113 | 3/13/2026 |
| 0.48.1 | 127 | 3/12/2026 |
| 0.48.0 | 116 | 3/11/2026 |
| 0.47.1 | 100 | 3/10/2026 |
| 0.47.0 | 91 | 3/9/2026 |
| 0.46.2 | 93 | 3/9/2026 |
| 0.46.1 | 90 | 3/8/2026 |
| 0.46.0 | 89 | 3/8/2026 |
| 0.45.3 | 100 | 3/3/2026 |
| 0.45.2 | 95 | 3/3/2026 |
| 0.45.1 | 92 | 3/3/2026 |
| 0.45.0 | 100 | 3/2/2026 |
| 0.44.1 | 100 | 3/1/2026 |
| 0.44.0 | 102 | 2/25/2026 |
| 0.43.0 | 127 | 1/31/2026 |