Files
EonaCat.FastBin/README.md
2025-11-01 11:57:44 +01:00

302 lines
8.0 KiB
Markdown

# EonaCat.FastBin
A blazingly fast, enterprise-grade binary serialization library for .NET with built-in networking capabilities.
## 🚀 Features
- **⚡ Ultra-fast** - Binary format optimized for speed, outperforms JSON and MessagePack
- **🔄 Complete object graph support** - Handles nested objects, circular references, and polymorphism
- **📦 Zero configuration** - Works with any type out of the box
- **🌐 Built-in networking** - TCP client/server with RPC support included
- **🎯 Type-safe** - Strongly-typed API with full generic support
- **🔒 Thread-safe** - Safe for concurrent serialization/deserialization
- **📱 Cross-platform** - .NET Standard 2.1 compatible
## 📊 Performance
EonaCat.FastBin uses several optimization techniques to achieve superior performance:
- **Binary format** - No text parsing overhead
- **7-bit integer encoding** - Compact representation of small numbers
- **Type caching** - Reflection performed only once per type
- **Reference tracking** - Objects serialized once, referenced thereafter
- **Zero-copy operations** - Direct memory access where possible
## 🎯 Quick Start
### Basic Serialization
```csharp
using EonaCat.FastBin;
// Serialize any object
var user = new User { Id = 1, Name = "Brasser", Email = "brasser@example.com" };
byte[] data = EonaCat.FastBin.Serialize(user);
// Deserialize back
var restored = EonaCat.FastBin.Deserialize<User>(data);
```
### Complex Objects
```csharp
// Works with nested objects
var order = new Order
{
OrderId = Guid.NewGuid(),
TotalAmount = 299.99m,
Items = new List<OrderItem>
{
new OrderItem { ProductName = "Laptop", Quantity = 1, Price = 299.99m }
}
};
byte[] data = EonaCat.FastBin.Serialize(order);
var restored = EonaCat.FastBin.Deserialize<Order>(data);
```
### Collections
```csharp
// Lists
var users = new List<User> { user1, user2, user3 };
byte[] data = EonaCat.FastBin.Serialize(users);
// Dictionaries
var userMap = new Dictionary<int, User>
{
[1] = user1,
[2] = user2
};
byte[] data2 = EonaCat.FastBin.Serialize(userMap);
// Arrays
var userArray = new User[] { user1, user2 };
byte[] data3 = EonaCat.FastBin.Serialize(userArray);
```
### Circular References
```csharp
// Self-referencing objects work automatically
var manager = new User { Id = 1, Name = "Manager" };
var employee = new User { Id = 2, Name = "Brasser", Manager = manager };
manager.Manager = manager; // Circular reference
byte[] data = EonaCat.FastBin.Serialize(employee);
var restored = EonaCat.FastBin.Deserialize<User>(data);
// Reference integrity maintained
Console.WriteLine(ReferenceEquals(restored.Manager, restored.Manager.Manager)); // True
```
### Polymorphism
```csharp
// Handles polymorphic types automatically
object[] items = new object[]
{
"A string",
42,
new User { Id = 1, Name = "Brasser" },
new Order { OrderId = Guid.NewGuid() }
};
byte[] data = EonaCat.FastBin.Serialize(items);
var restored = EonaCat.FastBin.Deserialize<object[]>(data);
// Types preserved correctly
Console.WriteLine(restored[0].GetType()); // System.String
Console.WriteLine(restored[2].GetType()); // User
```
## 🌐 Networking
### Server Setup
```csharp
var server = new FastServer();
// Register handlers
server.RegisterHandler<GetUserRequest, User>("GetUser", request =>
{
// Your business logic here
return database.GetUser(request.UserId);
});
server.RegisterHandler<CreateOrderRequest, CreateOrderResponse>("CreateOrder", async request =>
{
// Async handlers supported
var order = await orderService.CreateOrderAsync(request);
return new CreateOrderResponse { OrderId = order.Id, Message = "Success" };
});
// Start server
await server.StartAsync(5000);
```
### Client Usage
```csharp
using (var client = new FastClient())
{
await client.ConnectAsync("localhost", 5000);
// Make RPC calls
var user = await client.CallAsync<GetUserRequest, User>(
"GetUser",
new GetUserRequest { UserId = 123 }
);
var response = await client.CallAsync<CreateOrderRequest, CreateOrderResponse>(
"CreateOrder",
new CreateOrderRequest
{
UserId = 123,
Items = orderItems
}
);
}
```
## 📋 Supported Types
### Primitives
- All numeric types: `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `float`, `double`, `decimal`
- `bool`, `char`, `string`
- `DateTime`, `Guid`
- Enums
### Collections
- Arrays: `T[]`
- Lists: `List<T>`, `IList`, `IList<T>`
- Dictionaries: `Dictionary<K,V>`, `IDictionary`, `IDictionary<K,V>`
### Complex Types
- Classes (public and non-public fields)
- Structs
- Nested objects
- Generic types
- Polymorphic types
- Self-referencing objects
- Circular references
## 🔧 Advanced Usage
### Custom Domain Models
```csharp
public class Customer
{
public int Id;
public string Name;
public string Email;
public DateTime CreatedAt;
public Address ShippingAddress;
public List<Order> Orders;
public Customer ReferredBy; // Self-reference supported
}
public class Address
{
public string Street;
public string City;
public string ZipCode;
public string Country;
}
```
No attributes or special configuration needed - just define your classes normally!
### Error Handling (Networking)
```csharp
try
{
var result = await client.CallAsync<Request, Response>("Route", request);
}
catch (Exception ex)
{
// Handle network errors, deserialization errors, or handler exceptions
Console.WriteLine($"RPC failed: {ex.Message}");
}
```
### Server Shutdown
```csharp
// Graceful shutdown
server.Stop();
```
## 🏗️ Architecture
### Binary Format
EonaCat.FastBin uses a compact binary format with the following features:
1. **Type markers** - Single byte to identify data type
2. **7-bit encoding** - Variable-length integers for efficiency
3. **Reference tracking** - Objects assigned IDs, referenced by ID on subsequent encounters
4. **Type polymorphism** - Actual type stored when different from declared type
5. **Field ordering** - Consistent ordering by name for versioning
### Networking Protocol
1. **Message framing** - 4-byte length prefix
2. **Request/Response** - Structured messages with route and data
3. **Error handling** - Exceptions marshaled back to client
4. **Type safety** - Generic request/response types
## ⚠️ Limitations & Considerations
- **Private fields** - Serializes all fields (public and private)
- **Properties** - Only backing fields are serialized
- **Versioning** - Adding/removing fields requires redeployment (no built-in versioning)
- **Security** - No encryption built-in (use TLS/SSL at transport layer)
- **Large objects** - Keep network messages under 2GB (int.MaxValue)
## 🧪 Testing
The included example application demonstrates:
1. ✅ Basic serialization of primitives and collections
2. ✅ Complex nested object graphs
3. ✅ Self-referencing and circular references
4. ✅ Polymorphic type handling
5. ✅ Client-server RPC communication
## 🔄 Migration Guide
### From JSON.NET
```csharp
// Before (JSON.NET)
string json = JsonConvert.SerializeObject(obj);
var restored = JsonConvert.DeserializeObject<T>(json);
// After (EonaCat.FastBin)
byte[] data = FastBin.Serialize(obj);
var restored = FastBin.Deserialize<T>(data);
```
### From MessagePack
```csharp
// Before (MessagePack)
byte[] data = MessagePackSerializer.Serialize(obj);
var restored = MessagePackSerializer.Deserialize<T>(data);
// After (EonaCat.FastBin) - Same API!
byte[] data = FastBin.Serialize(obj);
var restored = FastBin.Deserialize<T>(data);
```
## 📝 Best Practices
1. **Reuse clients** - Create one `FastClient` per connection, reuse for multiple calls
2. **Dispose properly** - Always dispose clients: `using (var client = new FastClient())`
3. **Handler registration** - Register all handlers before calling `StartAsync()`
4. **Error handling** - Always wrap RPC calls in try-catch
5. **Thread safety** - `FastBin` class is thread-safe, instances are not
6. **Network timeout** - Implement timeouts at the TCP socket level if needed