161 lines
5.0 KiB
Markdown
161 lines
5.0 KiB
Markdown
# EonaCat.FastWriter
|
|
|
|
A high-performance serialization library.
|
|
Custom serializer for maximum speed and minimal allocations.
|
|
|
|
---
|
|
|
|
Optional Tcp server and client with auto-reconnect and broadcast support.
|
|
|
|
## Features
|
|
|
|
- **Typed messaging**: Send/receive objects of any type `T` using a fast custom serializer.
|
|
- **Raw byte messaging**: Send/receive arbitrary byte arrays for raw TCP servers/clients.
|
|
- **Dynamic mode switching**: Both server and client can switch between typed and raw mode at runtime using the `UseRaw` property.
|
|
- **Auto-reconnect**: Client automatically reconnects on connection loss.
|
|
- **Broadcast**: Send messages to all connected clients.
|
|
- **Nicknames**: Optional support for assigning nicknames to clients.
|
|
|
|
---
|
|
|
|
## Installation
|
|
|
|
```csharp
|
|
Install-Package EonaCat.FastWriter
|
|
```
|
|
|
|
Include the `EonaCat.FastWriter` namespace and all relevant classes in your project:
|
|
|
|
- `Server<T>`
|
|
- `Client<T>`
|
|
- `FastSerializer`, `FastReader`, `FastWriter`, `Dispatcher`
|
|
|
|
No external dependencies required.
|
|
|
|
---
|
|
|
|
## Usage
|
|
|
|
# Example application:
|
|
|
|
```csharp
|
|
using EonaCat.FastWriter;
|
|
|
|
internal class Program
|
|
{
|
|
private static async Task Main(string[] args)
|
|
{
|
|
// Test serialization for simple objects
|
|
var user = new User
|
|
{
|
|
Id = 1,
|
|
Name = "Alice",
|
|
IsAdmin = true,
|
|
Home = new Address { Street = "123 Main St", City = "Wonderland" }
|
|
};
|
|
|
|
byte[] data1 = FastSerializer.Serialize(user);
|
|
User clone = FastSerializer.Deserialize<User>(data1);
|
|
|
|
Console.WriteLine($"User clone: {clone.Name}, Admin={clone.IsAdmin}, City={clone.Home.City}");
|
|
|
|
// Test big collections
|
|
var numbers = new List<int>();
|
|
for (int i = 0; i < 100_000; i++)
|
|
{
|
|
numbers.Add(i);
|
|
}
|
|
|
|
byte[] data2 = FastSerializer.Serialize(numbers);
|
|
var copy1 = FastSerializer.Deserialize<List<int>>(data2);
|
|
|
|
Console.WriteLine($"Big list count: {copy1.Count}, First={copy1[0]}, Last={copy1[^1]}");
|
|
|
|
// Test array of strings
|
|
string[] names = { "A", "B", "C", "D", "E" };
|
|
var data3 = FastSerializer.Serialize(names);
|
|
var copy2 = FastSerializer.Deserialize<string[]>(data3);
|
|
|
|
Console.WriteLine($"String array length: {copy2.Length}, Second={copy2[1]}");
|
|
|
|
// Test nested collections
|
|
var users = new List<User>();
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
users.Add(new User
|
|
{
|
|
Id = i,
|
|
Name = $"User{i}",
|
|
IsAdmin = i % 2 == 0,
|
|
Home = new Address { Street = $"Street {i}", City = $"City {i}" }
|
|
});
|
|
}
|
|
|
|
byte[] data4 = FastSerializer.Serialize(users);
|
|
var copy3 = FastSerializer.Deserialize<List<User>>(data4);
|
|
|
|
Console.WriteLine($"Nested list count: {copy3.Count}, Last user city: {copy3[^1].Home.City}");
|
|
|
|
// Test dictionary
|
|
var dict = new Dictionary<string, User>();
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
dict[$"key{i}"] = new User { Id = i, Name = $"DUser{i}", Home = new Address { Street = $"S{i}", City = $"C{i}" } };
|
|
}
|
|
|
|
byte[] data5 = FastSerializer.Serialize(dict);
|
|
var copy4 = FastSerializer.Deserialize<Dictionary<string, User>>(data5);
|
|
|
|
Console.WriteLine($"Dictionary count: {copy4.Count}, key2 user name: {copy4["key2"].Name}");
|
|
|
|
// Server and Client test with messages
|
|
var server = new Server<Message>(12345);
|
|
|
|
server.MessageReceived += async (msg, client) =>
|
|
{
|
|
Console.WriteLine($"Server received: {msg.Text}, Number={msg.Number}");
|
|
await server.SendAsync(new Message { Text = "Ack: " + msg.Text, Number = msg.Number }, client);
|
|
};
|
|
|
|
_ = server.StartAsync();
|
|
|
|
var client = new Client<Message>("127.0.0.1", 12345);
|
|
|
|
client.MessageReceived += async msg =>
|
|
{
|
|
Console.WriteLine($"Client received: {msg.Text}, Number={msg.Number}");
|
|
await client.SendAsync(new Message { Text = $"Got your {msg.Number}", Number = 999 });
|
|
};
|
|
|
|
await client.ConnectAsync();
|
|
await client.SendAsync(new Message { Text = "Hello Server", Number = 123 });
|
|
|
|
// Send nested objects and big collections through server
|
|
await client.SendAsync(new Message { Text = $"Nested test: {copy3[0].Name}", Number = copy3.Count });
|
|
await client.SendAsync(new Message { Text = $"Big list last value: {copy1[^1]}", Number = copy1.Count });
|
|
|
|
Console.WriteLine("Press any key to exit...");
|
|
Console.ReadKey();
|
|
}
|
|
}
|
|
|
|
public class Address
|
|
{
|
|
public string Street { get; set; } = "";
|
|
public string City { get; set; } = "";
|
|
}
|
|
|
|
public class User
|
|
{
|
|
public int Id { get; set; }
|
|
public string Name { get; set; } = "";
|
|
public bool IsAdmin { get; set; }
|
|
public Address Home { get; set; } = new Address();
|
|
}
|
|
|
|
public class Message
|
|
{
|
|
public string Text { get; set; } = "";
|
|
public int Number { get; set; }
|
|
}
|
|
``` |