解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
大石头 authored at 2018-05-15 21:21:05
2.42 KiB
X
using System.Net;
using System.Net.Sockets;
using NewLife.Data;
using NewLife.Messaging;
using NewLife.Net;
using Xunit;

namespace XUnitTest.Net;

/// <summary>无等待方应答消息测试</summary>
/// <remarks>
/// 服务端主动推送 Reply=true 的应答,而客户端没有挂起请求(匹配队列为空)时:
/// 事件仍全量可见,匹配未命中路径必须安全归还拥有缓冲,不能出现二次归还或状态污染。
/// </remarks>
[Collection("Net")]
public class UnmatchedReplyTests
{
    [Theory(DisplayName = "无等待方应答:事件全量可见且缓冲安全归还")]
    [InlineData(256)]
    [InlineData(60_000)]
    public async Task UnsolicitedReply_NoWaiter(Int32 payloadSize)
    {
        const Int32 pushCount = 8;

        using var server = new NetServer
        {
            Port = 0,
            ProtocolType = NetType.Tcp,
            AddressFamily = AddressFamily.InterNetwork,
        };
        server.Protocol = new SrmpCodec();
        server.Received += (s, e) =>
        {
            if (s is INetSession session && e.Message is DefaultMessage req)
            {
                // 1条配对应答(供客户端等待方匹配),随后为空队列推送多条无等待方应答
                for (var i = 0; i < pushCount + 1; i++)
                {
                    var reply = req.CreateReply();
                    reply.SetBody(new ArrayPacket(new Byte[payloadSize]));
                    session.SendMessage(reply);
                }
            }
        };
        server.Start();

        using var client = new NetClient($"tcp://127.0.0.1:{server.Port}");
        client.Protocol = new SrmpCodec();
        client.Timeout = 15_000;

        var received = 0;
        var allDone = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
        client.Received += (s, e) =>
        {
            if (Interlocked.Increment(ref received) >= pushCount + 1) allDone.TrySetResult();
        };
        client.Open();

        // 建立并清空匹配队列;随后到达的推送应答全部走"无等待方"路径
        var request = new DefaultMessage();
        request.SetBody(new ArrayPacket(new Byte[16]));
        var resp = await client.SendMessageAsync(request);
        (resp as IDisposable)?.Dispose();

        await allDone.Task.WaitAsync(TimeSpan.FromSeconds(15));
        Assert.True(received >= pushCount + 1, $"只收到 {received} 条应答");
    }
}