Frame Reader và Sender
Trên trang này
Namespaces: Nalix.SDK.Transport.Internal, Nalix.Environment.Sequencing
Assembly: Nalix.SDK
Mỗi phiên cụ thể trong Nalix.SDK ủy thác I/O truyền tải mức thấp, phân mảnh, các biến đổi FramePipeline (nén LZ4 và mã hóa AEAD), và kiểm tra cửa sổ replay cho một cặp reader/sender nội bộ cùng một SequenceCounter không khóa.
Ánh xạ mã nguồn
src/Nalix.SDK/Transport/Internal/Tcp/TcpFrameReader.cssrc/Nalix.SDK/Transport/Internal/Tcp/TcpFrameSender.cssrc/Nalix.SDK/Transport/Internal/Udp/UdpFrameReader.cssrc/Nalix.SDK/Transport/Internal/Udp/UdpFrameSender.cssrc/Nalix.SDK/Transport/Internal/Ws/WsFrameReader.cssrc/Nalix.SDK/Transport/Internal/Ws/WsFrameSender.cssrc/Nalix.Environment/Sequencing/SequenceCounter.cs
So sánh khung truyền tải
| Transport | Reader / Sender | Khung trên dây | Phân mảnh | Bảo vệ replay / sequence |
|---|---|---|---|---|
TCP (TcpSession) | TcpFrameReader / TcpFrameSender | Tiền tố độ dài khung tổng ushort 2 byte little-endian (HeaderSize = 2) | Chia nhỏ FragmentHeader khi gửi (>= MaxChunkSize) / FragmentAssembler khi nhận | SequenceCounter.IsValid(seq, TcpWindow) (cửa sổ trượt 1024 bit) |
UDP (UdpSession) | UdpFrameReader / UdpFrameSender | [8B SessionToken (outbound)][Payload][4B XxHash32 MAC] (<= MaxUdpDatagramSize) | Không có (chỉ kiểm tra MTU của một datagram) | SequenceCounter.IsValid(seq, UdpWindow) (cửa sổ trượt 512 bit) |
WebSocket (WebSocketSession) | WsFrameReader / WsFrameSender | WebSocketMessageType.Binary (khung EndOfMessage) | FragmentAssembler khi nhận (khi gửi, thông điệp binary WebSocket hoàn chỉnh được gửi trực tiếp) | SequenceCounter.IsValid(seq, TcpWindow) (cửa sổ trượt 1024 bit) |
Pipeline biến đổi gửi & nhận
flowchart LR
subgraph Outbound["Outbound (Tcp/Udp/WsFrameSender)"]
P1["Serialized BufferLease"] --> P2["FramePipeline.ProcessOutbound<br/>(LZ4 Compress -> AEAD Encrypt with SequenceCounter.Next())"]
P2 --> P3["FragmentHeader Chunking (TCP if >= MaxChunkSize)<br/>or 8B Token + 4B XxHash32 MAC (UDP)"]
P3 --> P4["Socket / ClientWebSocket Send"]
end
subgraph Inbound["Inbound (Tcp/Udp/WsFrameReader)"]
R1["Socket / ClientWebSocket Receive"] --> R2["FragmentAssembler (TCP/WS)<br/>or 4B XxHash32 MAC Check (UDP)"]
R2 --> R3["FramePipeline.ProcessInbound<br/>(AEAD Decrypt -> LZ4 Decompress)"]
R3 --> R4["SequenceCounter.IsValid(seq, window)"]
R4 --> R5["HandleReceiveMessage(IBufferLease)"]
endCác bất biến nội bộ quan trọng
- Gửi đi được tuần tự hóa:
TcpFrameSendervàWsFrameSenderbảo vệ việc ghi socket bằngSemaphoreSlim(1, 1)(_sendLock), nên các lời gọiSendAsyncđồng thời không bao giờ xen kẽ khung hoặc phần chia nhỏ trên stream. - Nén rồi mới mã hóa (đối xứng): Khung gửi đi chạy
FramePipeline.ProcessOutbound(nén payload có kích thước $\ge$CompressionOptions.MinSizeToCompresstrước khi mã hóa AEAD khiencrypt == true), còn khung nhận đi chạyFramePipeline.ProcessInbound(giải mãPacketFlags.ENCRYPTEDtrước khi giải nénPacketFlags.COMPRESSED). - Cửa sổ replay của
SequenceCounter: Theo dõi số sequence truyền tải 32-bit nhúng trong các khung đã mã hóa và loại bỏ các gói trùng lặp hoặc nằm ngoài cửa sổ trước khi chúng tớiOnMessageReceived.