AyCode.Core/AyCode.Services.Server.Tests/SignalRs/TestMultiSegmentProtocol.cs

53 lines
1.9 KiB
C#

using System.Buffers;
using System.Diagnostics.CodeAnalysis;
using AyCode.Services.SignalRs;
using Microsoft.AspNetCore.SignalR;
using Microsoft.AspNetCore.SignalR.Protocol;
namespace AyCode.Services.Server.Tests.SignalRs;
/// <summary>
/// Test protocol that forces multi-segment ReadOnlySequence parsing.
/// Splits serialized bytes into chunks before calling base.TryParseMessage,
/// exercising SequenceBinaryInput cross-boundary reads and SequenceToByteArray multi-segment paths.
/// </summary>
internal class TestMultiSegmentProtocol : AyCodeBinaryHubProtocol
{
private const int SegmentSize = 4096;
public override bool TryParseMessage(ref ReadOnlySequence<byte> input, IInvocationBinder binder,
[NotNullWhen(true)] out HubMessage? message)
{
// Temporarily bypass multi-segment to isolate the issue
return base.TryParseMessage(ref input, binder, out message);
}
private static ReadOnlySequence<byte> CreateMultiSegmentSequence(ReadOnlySequence<byte> source, int chunkSize)
{
var bytes = source.ToArray();
var first = new MemorySegment(bytes.AsMemory(0, Math.Min(chunkSize, bytes.Length)));
var current = first;
for (var offset = chunkSize; offset < bytes.Length; offset += chunkSize)
{
var length = Math.Min(chunkSize, bytes.Length - offset);
current = current.Append(bytes.AsMemory(offset, length));
}
return new ReadOnlySequence<byte>(first, 0, current, current.Memory.Length);
}
private sealed class MemorySegment : ReadOnlySequenceSegment<byte>
{
public MemorySegment(ReadOnlyMemory<byte> memory) => Memory = memory;
public MemorySegment Append(ReadOnlyMemory<byte> memory)
{
var next = new MemorySegment(memory) { RunningIndex = RunningIndex + Memory.Length };
Next = next;
return next;
}
}
}