MessageCodec 1.1.1
dotnet add package MessageCodec --version 1.1.1
NuGet\Install-Package MessageCodec -Version 1.1.1
<PackageReference Include="MessageCodec" Version="1.1.1" />
<PackageVersion Include="MessageCodec" Version="1.1.1" />
<PackageReference Include="MessageCodec" />
paket add MessageCodec --version 1.1.1
#r "nuget: MessageCodec, 1.1.1"
#:package MessageCodec@1.1.1
#addin nuget:?package=MessageCodec&version=1.1.1
#tool nuget:?package=MessageCodec&version=1.1.1
Binary Message Codec
A compact and efficient binary encoding library for real-time communication protocols.
Installation
dotnet add package MessageCodec
Quick Start
using BinaryMessageCodec;
// Create and encode a message
var message = new Message
{
Headers = new Dictionary<string, string>
{
{ "Content-Type", "application/json" },
{ "User-Agent", "MyApp/1.0" }
},
Payload = Encoding.UTF8.GetBytes("Hello, World!")
};
IMessageCodec codec = new BinaryMessageCodec();
byte[] encoded = codec.Encode(message);
// Decode back to message
Message decoded = codec.Decode(encoded);
Constraints
- Maximum 63 headers per message
- Header names and values: 1023 bytes each (ASCII only)
- Maximum payload size: 256 KiB
Error Handling
Throws MessageCodecException for invalid inputs or corrupted data.
Binary Message Encoding Scheme - Design Document
Encoding Scheme Design
Format Structure
The encoding uses a compact binary format optimized for the specific constraints:
[1 byte: Header Count (0-63)]
[Header Section: Variable length]
For each header:
[2 bytes: Name Length (0-1023)]
[N bytes: Name (ASCII)]
[2 bytes: Value Length (0-1023)]
[M bytes: Value (ASCII)]
[3 bytes: Payload Length (0-262144)]
[P bytes: Payload]
Design Decisions
Header Count (1 byte)
- Since max headers = 63, we can use 6 bits (0-63)
- Using full byte for simplicity and alignment
- Allows quick validation without reading entire message
Length Prefixes (2 bytes for headers, 3 bytes for payload)
- Header names/values: 1023 bytes max ? 10 bits needed ? use 2 bytes (16 bits)
- Payload: 256 KiB = 262,144 bytes ? 18 bits needed ? use 3 bytes (24 bits)
- Little-endian encoding for consistency with .NET runtime
- Enables zero-copy reading with span-based parsing
No Delimiters or Padding
- Length-prefixed approach eliminates need for delimiters
- No alignment padding needed (prioritizing size over alignment)
- Simplifies parsing logic and reduces message overhead
ASCII-Only Headers
- Direct byte copying (no UTF-8 encoding overhead)
- Validates headers are ASCII during encoding
- Efficient string construction during decoding
Efficiency Analysis
Overhead per message:
- Fixed: 4 bytes (1 header count + 3 payload length)
- Per header: 4 bytes + name length + value length
- Example: 5 headers with avg 10-byte names and 20-byte values = 154 bytes overhead
Performance characteristics:
- O(1) header count lookup
- O(n) encoding/decoding (unavoidable - must process all data)
- Sequential memory access pattern (cache-friendly)
- Minimal allocations using Span<byte> and stackalloc
Alternative Approaches Considered
- JSON/Text-based: Rejected due to size overhead and parsing cost
- Fixed-size fields: Rejected due to wasted space for small values
Assumptions
- Messages are self-contained (no streaming/chunking needed)
- Header order doesn't matter (using Dictionary)
- Duplicate header names overwrite (Dictionary behavior)
- Binary payload is opaque (no interpretation needed)
- Network byte order not required (local protocol assumption)
Part 2: Deployment & Operations
1. Packaging
My recommendation: NuGet Package
The IMessageCodec implementation should be packaged as a NuGet package for the following reasons:
Rationale:
- Reusability: Can be consumed by multiple .NET applications (signaling service, client SDKs, testing tools)
- Versioning: Semantic versioning allows controlled updates across services
- Dependency Management: NuGet handles transitive dependencies automatically
- CI/CD Integration: Easy to publish to private/public NuGet feeds from build pipelines
- Performance: Runs in-process (no network overhead like a containerized service)
Why NOT other options:
- Source-code module: Harder to version, no isolated testing
- Containerized service: Unnecessary network latency for CPU-bound operation
- Shared library: Platform-dependent, complex deployment
2. Deployment on AWS
Recommendation: ECS on Fargate with Application Load Balancer
Architecture:
Internet → Route 53 → ALB → ECS Fargate (Signaling Service) → ElastiCache/RDS
↓
Auto Scaling
Key AWS Services:
Amazon ECS with Fargate (Primary Compute)
- Why: Serverless containers, no EC2 management, per-second billing
- Runs signaling service containers consuming the codec NuGet package
- Task auto-scaling based on CPU/connection count
Application Load Balancer (ALB)
- Distributes WebSocket/HTTP traffic across ECS tasks
- Health checks ensure only healthy tasks receive traffic
- Supports sticky sessions for real-time connections
Route 53
- DNS routing with latency-based routing for multi-region
- Health checks for automatic failover
ElastiCache (Redis)
- Session state management for WebSocket connections
- Pub/Sub for message routing between service instances
CloudWatch + X-Ray
- Metrics, logs, and distributed tracing
- Custom metrics for codec performance
ECR (Elastic Container Registry)
- Stores Docker images of signaling service
High Availability:
- Multi-AZ deployment (minimum 2 AZs)
- Auto Scaling: Target tracking on CPU/connection metrics
- Health checks: ALB checks /health endpoint every 30s
Why NOT alternatives:
- Lambda: Cold starts unsuitable for WebSocket real-time requirements
- EC2 Auto Scaling: More ops overhead than Fargate
- EKS: Overkill for single service, higher complexity
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. 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. |
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.