TagBites.Net
1.0.3
Prefix Reserved
dotnet add package TagBites.Net --version 1.0.3
NuGet\Install-Package TagBites.Net -Version 1.0.3
<PackageReference Include="TagBites.Net" Version="1.0.3" />
<PackageVersion Include="TagBites.Net" Version="1.0.3" />
<PackageReference Include="TagBites.Net" />
paket add TagBites.Net --version 1.0.3
#r "nuget: TagBites.Net, 1.0.3"
#:package TagBites.Net@1.0.3
#addin nuget:?package=TagBites.Net&version=1.0.3
#tool nuget:?package=TagBites.Net&version=1.0.3
TagBites.Net
Lightweight and simple TCP client-server .NET library with RMI support.
Install
dotnet add package TagBites.Net
Targets netstandard2.0 and net7.0. The only dependency is Newtonsoft.Json, plus System.Reflection.DispatchProxy on netstandard2.0.
Chat example
A console chat. Every client sends text lines to the server, and the server broadcasts each message to the other clients, together with connect and disconnect notifications.
Client code
var client = new Client("127.0.0.1", 8200);
client.Received += (s, e) => Console.WriteLine(e.Message.ToString());
await client.ConnectAsync();
while (Console.ReadLine() is { } message)
await client.SendAsync(message);
Server code
var server = new Server("127.0.0.1", 8200);
server.ClientConnected += async (s, e) => await server.SendToAllAsync($"{e.Client} connected", e.Client);
server.ClientDisconnected += async (s, e) => await server.SendToAllAsync($"{e.Client} disconnected", e.Client);
server.Received += async (s, e) => await server.SendToAllAsync($"{e.Client}: {e.Message}", e.Client);
server.Listening = true; // starts a new thread
Console.ReadLine(); // for console application to prevent app from closing
In this example a string type is used for communication, but any serializable objects can be sent/received.
By default Newtonsoft.Json is used for serialization, but it can be replaced with a custom implementation.
Full example in this repository: samples/Chat.
Chat example using RMI (Remote Method Invocation)
The same chat, written as method calls instead of messages. Both sides share two interfaces: the client calls IChatServer.Send on the server, and the server calls IChatClient.OnMessage on every client. Serialization and dispatch happen behind the proxy returned by GetController<T>().
Client code
var client = new Client("127.0.0.1", 10500);
client.Use<IChatClient, ChatClient>();
await client.ConnectAsync();
while (Console.ReadLine() is { } message)
client.GetController<IChatServer>().Send(message);
The method Use<TControllerInterface, TController>() registers a controller that can be used by the server. The server side can use the IChatClient interface to execute methods implemented by ChatClient on the client's side. The client/server can register many controllers. The controller instance will be created on first use.
GetController<T>() returns a proxy implementing the interface registered on the remote side. Calling a method on it invokes that method on the remote side. A controller method takes primitive or serializable parameters and returns void, Task, or any primitive or serializable type.
Server code
var server = new Server("127.0.0.1", 10500);
server.Use<IChatServer, ChatServer>(client => new ChatServer { Client = client, Server = server });
server.ClientConnected += (s, e) =>
{
foreach (var client in server.GetClients())
if (client != e.Client)
client.GetController<IChatClient>().OnMessage(null, $"Client {e.Client.Identity} connected");
Console.WriteLine($"Client {e.Client.Identity} connected.");
};
server.ClientDisconnected += (s, e) =>
{
foreach (var client in server.GetClients())
client.GetController<IChatClient>().OnMessage(null, $"Client {e.Client.Identity} disconnected");
Console.WriteLine($"Client {e.Client.Identity} disconnected.");
};
server.Listening = true;
Console.ReadLine();
Classes
public interface IChatClient
{
void OnMessage(string userName, string message);
}
public class ChatClient : IChatClient
{
public void OnMessage(string userName, string message)
{
Console.WriteLine(userName == null ? message : $"{userName}: {message}");
}
}
public interface IChatServer
{
void Send(string message);
}
public class ChatServer : IChatServer
{
public Server Server { get; set; }
public ServerClient Client { get; set; }
public void Send(string message)
{
Console.WriteLine($"{Client.Identity}: {message}");
foreach (var client in Server.GetClients())
if (Client != client)
client.GetController<IChatClient>().OnMessage(Client.Identity?.ToString(), message);
}
}
Full example in this repository: samples/ChatWithControllers.
Limitations
There is no message size limit and no rate limiting, so both sides have to be trusted. Authentication is a callback, not a protocol, and credentials travel in plain text unless the connection uses a certificate.
Links
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.1)
- System.Reflection.DispatchProxy (>= 4.3.0)
-
net7.0
- Newtonsoft.Json (>= 13.0.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.3 | 111 | 8/14/2026 |
| 1.0.2 | 948 | 7/31/2024 |
| 1.0.1 | 212 | 7/30/2024 |
| 1.0.0 | 597 | 7/3/2023 |
| 1.0.0-beta4 | 880 | 7/15/2019 |
| 1.0.0-beta3 | 1,530 | 9/21/2018 |