Nalix là gì?
Nalix là framework mạng nhị phân thời gian thực, độ trễ thấp cho .NET 10, dành cho Blazor WebAssembly, MAUI và game server. Bạn định nghĩa packet là các lớp C#, viết handler theo opcode, và trao đổi dữ liệu qua TCP, UDP hoặc WebSocket từ client SDK của Nalix mà không có lớp HTTP ở giữa (README của Nalix).
Nalix là dự án mã nguồn mở theo giấy phép Apache-2.0, do Phan Phúc Nguyên (tác giả bài viết này) tạo ra và duy trì tại kho ppn-systems/nalix. Vì người viết cũng là tác giả dự án, mọi số liệu trong bài đều lấy từ tài liệu công khai của dự án và được ghi rõ là tự công bố.
Khi nào cần một thư viện mạng C# riêng thay vì SignalR hay gRPC
Phần lớn ứng dụng .NET nên dùng các lựa chọn quen thuộc như ASP.NET Core, SignalR hoặc gRPC: trưởng thành, tài liệu tốt, có client cho nhiều ngôn ngữ và chạy trên hạ tầng HTTP sẵn có. Nalix nhắm tới nhóm bài toán hẹp hơn: game server và ứng dụng thời gian thực, nơi rất nhiều gói tin nhỏ được gửi liên tục và độ trễ từng gói, lượng bộ nhớ cấp phát trên server thực sự quan trọng.
Ở nhóm bài toán đó, ba thứ thường gây tốn kém là lớp giao thức HTTP, định dạng tuần tự hóa tổng quát và cấp phát bộ nhớ trên mỗi tin nhắn (gây áp lực cho bộ thu gom rác). Nalix chọn khung nhị phân riêng, bộ tuần tự hóa sinh mã lúc biên dịch và đường xử lý dùng bộ nhớ đệm, packet tái sử dụng.
Nếu bạn đang so sánh các cách tiếp cận chung (TCP, UDP hay WebSocket, framing, tick rate) chứ chưa chọn thư viện cụ thể, hãy đọc bài trung lập lập trình mạng cho game server và hệ thống realtime bằng C# trước.
| Tiêu chí | Nalix | SignalR | gRPC (.NET) | MagicOnion |
|---|---|---|---|---|
| Định dạng truyền | Khung nhị phân riêng, tuần tự hóa sinh mã | JSON hoặc MessagePack qua HTTP | Protobuf qua HTTP/2 | MessagePack qua gRPC (HTTP/2) |
| Mã hóa | Tích hợp: bắt tay X25519, ghim khóa server, ChaCha20-Poly1305 mỗi packet | TLS (HTTPS) | TLS | TLS |
| Giao thức truyền | TCP, UDP, WebSocket | WebSocket, SSE, long polling | HTTP/2 (HTTP/3) | HTTP/2 |
| Native AOT | Có | Một phần | Có | Qua source generator |
| Client Blazor WASM | Có, qua WebSocket | Có | Chỉ gRPC-Web | Không |
Thiết kế: kiến trúc phân tầng và mô hình packet
Nalix được chia thành các gói NuGet theo tầng; mỗi gói chỉ phụ thuộc tầng thấp hơn và không có tham chiếu vòng, nên bạn chỉ cài những tầng cần thiết (README của Nalix).
- Tầng 0 – Nalix.Abstractions: hợp đồng, enum, không phụ thuộc gì.
- Tầng 1 – Nalix.Environment: thao tác IO cấp thấp, thuê/trả bộ đệm.
- Tầng 2 – Nalix.Codec (đóng khung, mã hóa, tuần tự hóa) và Nalix.Framework (định danh, DI, điều phối tác vụ).
- Tầng 3 – Nalix.Network (TCP/UDP, phiên), Nalix.Runtime (điều phối packet, middleware, giới hạn tốc độ), Nalix.SDK (phiên phía client).
- Tầng 4 – Nalix.Hosting: API host và builder kiểu Microsoft để khởi động nhanh.
Packet là lớp C# có thuộc tính và opcode
Mỗi packet là một lớp C# được đánh dấu bằng thuộc tính Packet và GenerateFormatter, khai báo opcode tĩnh (ví dụ 0x7001 trong mẫu HelloWorld) và thứ tự trường bằng SerializeOrder. Phía server, handler là phương thức gắn thuộc tính PacketOpcode; Nalix định tuyến packet đến đúng handler theo opcode.
Source generator và Roslyn analyzer
Bộ tuần tự hóa được sinh lúc biên dịch thay vì dùng reflection lúc chạy. Gói Nalix.Analyzers chứa Roslyn analyzer, code fix và source generator (đóng gói kèm Nalix.Abstractions) để bắt lỗi khai báo packet ngay khi biên dịch. Cách làm này cũng là điều kiện để mọi gói đều tương thích trimming và Native AOT.
Giảm cấp phát bộ nhớ
README mô tả đường xử lý nóng dùng bộ đệm và packet lấy từ pool. Trong mẫu HelloWorld, handler thuê packet phản hồi qua PacketFactory, dùng xong thì trả lại, nên các lần gọi lặp lại không cấp phát mới. Dự án nhắm .NET 10 và C# 14 để tận dụng Span, ref struct và thành viên static abstract trong interface cho opcode và formatter. Đây là kỹ thuật giảm cấp phát, không có nghĩa là hoàn toàn không cấp phát: benchmark của dự án vẫn đo được 56 byte mỗi tin nhắn trên server.
Giao thức truyền và middleware
TCP, UDP và WebSocket dùng chung một mô hình packet. Mẫu SecureMultiTransportHelloWorld chạy cả ba dưới một phiên bảo mật, gồm UDP có xác thực. Trình duyệt kết nối qua Blazor WebAssembly bằng WebSocket. Phía server có sẵn middleware phân quyền, giới hạn tốc độ, timeout, điều tiết lưu lượng, và cho phép thêm middleware riêng.
Bảo mật: X25519, ghim khóa server, ChaCha20-Poly1305 và nối lại phiên
Nalix tích hợp mã hóa vào giao thức, không cần chứng chỉ TLS. Giải thích ngắn gọn từng phần:
- X25519 (RFC 7748): hàm trao đổi khóa Diffie-Hellman trên đường cong Curve25519, mức an toàn khoảng 128 bit. Hai bên tạo ra một khóa bí mật chung mà không gửi khóa đó qua mạng (RFC 7748).
- Ghim khóa server (server key pinning): client biết trước khóa công khai của server, nên nếu kẻ đứng giữa giả mạo server bằng khóa khác, bắt tay thất bại. Đây là cách xác thực server thay cho chứng chỉ.
- ChaCha20-Poly1305 (RFC 8439): thuật toán mã hóa có xác thực (AEAD), vừa giữ bí mật nội dung vừa phát hiện nếu gói tin bị sửa. Nalix áp dụng cho từng packet (RFC 8439).
- Nối lại phiên (session resume): khi mất kết nối, client dùng token phiên để nối lại thay vì bắt tay lại từ đầu.
Đánh đổi cần biết
RFC 8439 yêu cầu nonce không được lặp lại với cùng một khóa; mọi giao thức tự xây dựa trên AEAD phải xử lý đúng điều này. Giao thức riêng cũng chưa có lịch sử kiểm chứng rộng như TLS. Nếu bạn cần tuân thủ chính sách yêu cầu TLS hoặc đi qua hạ tầng kiểm tra lưu lượng HTTPS, hãy cân nhắc kỹ. Chính sách báo cáo lỗ hổng của dự án nằm trong SECURITY.md.
Benchmark: đọc đúng các con số tự công bố
Mọi số liệu dưới đây là benchmark loopback do dự án tự công bố, chạy trên máy 4 vCPU: Ubuntu 24.04, Intel Xeon 2,10 GHz, .NET 10 (SDK 10.0.401), Release, trung vị của 3 lần chạy, payload 32 byte; mỗi framework dùng client riêng của nó. Dữ liệu thô nằm trong tài liệu network-comparison.
| Thư viện | p50 (µs) | p99 (µs) | ops/s, 64 client | Cấp phát server/tin (B) | CPU server/tin (µs) |
|---|---|---|---|---|---|
| Nalix TCP | 52,2 | 154,9 | 74.791 | 56 | 29,3 |
| Nalix WebSocket | 55,5 | 159,6 | 69.135 | 192 | 27,1 |
| SignalR (WebSocket, MessagePack) | 76,3 | 190,8 | 71.871 | 672 | 21,8 |
| gRPC bidi stream (h2c) | 68,4 | 167,3 | 77.648 | 264 | 21,9 |
| MagicOnion StreamingHub | 74,2 | 173,8 | 67.501 | 200 | 26,3 |
| Nalix TCP + X25519/ChaCha20-Poly1305 | 57,6 | 154,3 | 63.309 | 56 | 34,2 |
| gRPC bidi stream + TLS | 100,4 | 282,6 | 57.791 | 812 | 30,4 |
Cách đọc kết quả
- Nalix có p50 một client và cấp phát server mỗi tin thấp nhất trong các framework đầy đủ được đo; socket viết tay (30,9 µs) và WebSocket Kestrel thuần (45,0 µs) vẫn nhanh hơn.
- Về thông lượng 64 client, gRPC bidi stream cao hơn ở payload 32 byte; ở 1 KB, SignalR và gRPC cao hơn Nalix. CPU server mỗi tin của SignalR và gRPC thấp hơn.
- README tự nêu giới hạn: chạy loopback, bộ tạo tải và server dùng chung lõi CPU, nên năng lực trên máy thật có card mạng riêng sẽ khác; các dòng mã hóa so AEAD từng packet với TLS dạng luồng.
- Hãy tự chạy benchmark trên phần cứng và tải thực của bạn trước khi quyết định.
Khi nào KHÔNG nên dùng Nalix
README của dự án liệt kê rõ các trường hợp nên chọn công cụ khác:
- Cần tương thích HTTP/REST, proxy hoặc API gateway hiểu ngữ nghĩa HTTP: dùng gRPC hoặc ASP.NET Core.
- Có client nhiều ngôn ngữ (JavaScript, Go, Python, Java): Nalix chỉ có client SDK cho .NET; gRPC và SignalR có client cho nhiều ngôn ngữ.
- Đang dùng .NET 8/9 hoặc .NET Framework: Nalix chỉ nhắm .NET 10.
- Xây client Unity: Unity chưa chạy .NET 10 nên SDK chưa dùng được; MagicOnion hỗ trợ Unity.
Thêm góc nhìn từ người viết
Ngoài danh sách trên, nếu đội ngũ của bạn chưa có nhu cầu đo đếm độ trễ ở mức micro giây, chi phí học và vận hành một giao thức riêng thường không đáng. SignalR và gRPC là lựa chọn an toàn hơn cho phần lớn ứng dụng doanh nghiệp.
Bắt đầu với Nalix
Nếu bạn đang xây backend .NET cho các hệ thống AI, xem thêm bài xây backend AI bằng C# và .NET.
- Cài .NET SDK 10 và dùng C# 14.
- Thêm gói Nalix.Hosting cho server, Nalix.SDK cho client; analyzer và source generator đi kèm Nalix.Abstractions.
- Chạy mẫu samples/HelloWorld: mở server bằng dotnet run cho dự án HelloWorld.Server, rồi chạy HelloWorld.Client ở terminal khác.
- Để bật mã hóa: gọi UseSecureConnections trên builder phía server và HandshakeAsync sau khi client kết nối (xem mẫu SecureMultiTransportHelloWorld).
- Xem thêm các mẫu ChatRoom (đẩy dữ liệu từ server) và BlazorWasm (client trình duyệt).
Câu hỏi thường gặp
Nalix có miễn phí không?
Có. Nalix là mã nguồn mở theo giấy phép Apache License 2.0, cho phép dùng trong dự án thương mại theo điều kiện của giấy phép.
Nalix có thay thế được SignalR hay gRPC không?
Không phải trong mọi trường hợp. Nalix phù hợp khi client là .NET 10 và cần độ trễ, cấp phát thấp. Nếu cần HTTP, client nhiều ngôn ngữ hoặc Unity, SignalR, gRPC hay MagicOnion phù hợp hơn.
Nalix có hỗ trợ Unity không?
Hiện chưa. Unity chưa chạy .NET 10 nên SDK của Nalix chưa dùng được trong Unity; README gợi ý MagicOnion cho trường hợp này.
Vì sao Nalix không dùng TLS mà tự mã hóa?
Nalix tích hợp bắt tay X25519 với ghim khóa server và mã hóa ChaCha20-Poly1305 cho từng packet, nên không cần chứng chỉ. Đổi lại, đây là giao thức riêng, nên cần cân nhắc nếu tổ chức bắt buộc dùng TLS.
Benchmark của Nalix có đáng tin không?
Đó là benchmark loopback do dự án tự công bố trên máy 4 vCPU, có dữ liệu thô và ghi chú giới hạn. Hãy coi là điểm tham khảo và tự đo trên môi trường của bạn.