302 lines
8.0 KiB
Markdown
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 |