From 4ab8ede6ca26da731c2ee5569f766dc8ce2b33a1 Mon Sep 17 00:00:00 2001 From: Loretta Date: Fri, 6 Mar 2026 14:26:48 +0100 Subject: [PATCH] Switch to binary serialization, update compression to GZip - Changed default SignalR message serialization from JSON to binary. - Updated AcSerializerType enum values: Binary=0, Json=1. - Disabled string caching when intern table is present. - Replaced Brotli with GZip for JSON compression in comments and logic. - Refactored SignalResponseDataMessage deserialization for improved error handling. --- ...serializer.BinaryDeserializationContext.cs | 4 ++- .../Jsons/AcJsonSerializerOptions.cs | 4 +-- .../SignalRs/AcSignalRSendToClientService.cs | 3 +- .../SignalRs/IAcSignalRHubClient.cs | 33 ++++++++++--------- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs index 4fe7355..de4ba2e 100644 --- a/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs +++ b/AyCode.Core/Serializers/Binaries/AcBinaryDeserializer.BinaryDeserializationContext.cs @@ -18,7 +18,7 @@ public static partial class AcBinaryDeserializer private Dictionary? _objectReferences; private Dictionary? _stringCache; private readonly byte _minStringInternLength; - private readonly bool _useStringCaching; + private bool _useStringCaching; private readonly int _maxCachedStringLength; public bool HasMetadata { get; private set; } @@ -107,6 +107,8 @@ public static partial class AcBinaryDeserializer if (hasInternTable) { + _useStringCaching = false; + var internCount = (int)ReadVarUInt(); _internedStrings = new List(internCount); for (var i = 0; i < internCount; i++) diff --git a/AyCode.Core/Serializers/Jsons/AcJsonSerializerOptions.cs b/AyCode.Core/Serializers/Jsons/AcJsonSerializerOptions.cs index 0addd5a..5d5777b 100644 --- a/AyCode.Core/Serializers/Jsons/AcJsonSerializerOptions.cs +++ b/AyCode.Core/Serializers/Jsons/AcJsonSerializerOptions.cs @@ -2,8 +2,8 @@ namespace AyCode.Core.Serializers.Jsons; public enum AcSerializerType : byte { - Json = 0, - Binary = 1, + Binary = 0, + Json = 1, Toon = 2, } diff --git a/AyCode.Services.Server/SignalRs/AcSignalRSendToClientService.cs b/AyCode.Services.Server/SignalRs/AcSignalRSendToClientService.cs index ef64b3b..f2d3e68 100644 --- a/AyCode.Services.Server/SignalRs/AcSignalRSendToClientService.cs +++ b/AyCode.Services.Server/SignalRs/AcSignalRSendToClientService.cs @@ -1,6 +1,7 @@ using AyCode.Core.Extensions; using AyCode.Core.Helpers; using AyCode.Core.Loggers; +using AyCode.Core.Serializers.Binaries; using AyCode.Core.Serializers.Jsons; using AyCode.Services.SignalRs; using Microsoft.AspNetCore.SignalR; @@ -14,7 +15,7 @@ public abstract class AcSignalRSendToClientService(messageTag)}"); diff --git a/AyCode.Services/SignalRs/IAcSignalRHubClient.cs b/AyCode.Services/SignalRs/IAcSignalRHubClient.cs index b39035a..b3f8750 100644 --- a/AyCode.Services/SignalRs/IAcSignalRHubClient.cs +++ b/AyCode.Services/SignalRs/IAcSignalRHubClient.cs @@ -136,7 +136,7 @@ public enum SignalResponseStatus : byte /// /// Unified signal response message that supports both JSON and Binary serialization. -/// JSON mode uses Brotli compression for reduced payload size. +/// JSON mode uses GZip compression for reduced payload size. /// Optimized: uses pooled buffers for decompression, zero-copy deserialization path. /// public sealed class SignalResponseDataMessage : ISignalResponseMessage, IDisposable @@ -182,28 +182,29 @@ public sealed class SignalResponseDataMessage : ISignalResponseMessage, IDisposa if (_cachedResponseData != null) return (T)_cachedResponseData; if (ResponseData == null) return default; - if (DataSerializerType == AcSerializerType.Binary) + try { - try + if (DataSerializerType == AcSerializerType.Binary) { // Log diagnostics if enabled LogResponseDataDiagnostics(); - + return (T)(_cachedResponseData = ResponseData.BinaryTo()!); } - catch (Exception ex) - { - // Log detailed error diagnostics - LogResponseDataError(ex); - throw; - } - } - // Decompress Brotli to pooled buffer and deserialize directly - EnsureDecompressed(); - var result = AcJsonDeserializer.Deserialize(new ReadOnlySpan(_rentedDecompressedBuffer, 0, _decompressedLength)); - _cachedResponseData = result; - return result; + // Decompress GZip to pooled buffer and deserialize directly + EnsureDecompressed(); + + var result = AcJsonDeserializer.Deserialize(new ReadOnlySpan(_rentedDecompressedBuffer, 0, _decompressedLength)); + _cachedResponseData = result; + return result; + } + catch (Exception ex) + { + // Log detailed error diagnostics + LogResponseDataError(ex); + throw; + } } private void LogResponseDataDiagnostics()