84 lines
3.1 KiB
C#
84 lines
3.1 KiB
C#
using System.Buffers;
|
|
using AyCode.Core;
|
|
using AyCode.Core.Extensions;
|
|
using AyCode.Core.Tests.TestModels;
|
|
using AyCode.Services.Server.SignalRs;
|
|
using AyCode.Services.SignalRs;
|
|
using AyCode.Services.Tests.SignalRs;
|
|
using Microsoft.AspNetCore.SignalR.Client;
|
|
using Microsoft.AspNetCore.SignalR.Protocol;
|
|
|
|
namespace AyCode.Services.Server.Tests.SignalRs;
|
|
|
|
/// <summary>
|
|
/// Testable SignalR client that allows testing without real HubConnection.
|
|
/// Routes all messages through AyCodeBinaryHubProtocol with multi-segment splitting
|
|
/// to exercise the full serialization/deserialization pipeline.
|
|
/// </summary>
|
|
public class TestableSignalRClient2 : AcSignalRClientBase, IAcSignalRHubItemServer
|
|
{
|
|
private HubConnectionState _connectionState = HubConnectionState.Connected;
|
|
private readonly TestableSignalRHub2 _signalRHub;
|
|
private readonly TestMultiSegmentProtocol _protocol = new();
|
|
private readonly TestInvocationBinder _binder = new();
|
|
|
|
/// <summary>
|
|
/// Testable SignalR client that allows testing without real HubConnection.
|
|
/// </summary>
|
|
public TestableSignalRClient2(TestableSignalRHub2 signalRHub, TestLogger logger) : base(logger)
|
|
{
|
|
MsDelay = 0;
|
|
MsFirstDelay = 0;
|
|
|
|
_signalRHub = signalRHub;
|
|
}
|
|
|
|
#region Override virtual methods for testing
|
|
|
|
protected override Task MessageReceived(int messageTag, SignalParams signalParams, object data)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
protected override HubConnectionState GetConnectionState() => _connectionState;
|
|
|
|
protected override bool IsConnected() => _connectionState == HubConnectionState.Connected;
|
|
|
|
protected override Task StartConnectionInternal()
|
|
{
|
|
_connectionState = HubConnectionState.Connected;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
protected override Task StopConnectionInternal()
|
|
{
|
|
_connectionState = HubConnectionState.Disconnected;
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
protected override ValueTask DisposeConnectionInternal() => ValueTask.CompletedTask;
|
|
|
|
protected override Task SendToHubAsync(int messageTag, int? requestId, SignalParams signalParams, object? data)
|
|
{
|
|
// Protocol round-trip: serialize → multi-segment split → deserialize
|
|
var invocation = new InvocationMessage(
|
|
nameof(IAcSignalRHubClient.OnReceiveMessage),
|
|
[messageTag, requestId, signalParams, data ?? Array.Empty<byte>()]);
|
|
|
|
var bytes = _protocol.GetMessageBytes(invocation);
|
|
var sequence = new ReadOnlySequence<byte>(bytes);
|
|
if (!_protocol.TryParseMessage(ref sequence, _binder, out var parsed) || parsed is not InvocationMessage invMsg)
|
|
throw new InvalidOperationException(
|
|
$"Protocol round-trip failed. ByteCount={bytes.Length}, Parsed={parsed?.GetType().Name ?? "null"}, " +
|
|
$"Tag={messageTag}, RequestId={requestId}, DataType={data?.GetType().Name ?? "null"}");
|
|
|
|
var args = invMsg.Arguments;
|
|
return _signalRHub.OnReceiveMessage(
|
|
(int)args[0]!, (int?)args[1], (SignalParams)args[2]!, args[3]!);
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
|
|
|