[fix]修正UdpServer在接收广播时连续启动接收的错误,在StarAgent中,此时可能收到广播包,SocketFlags是Broadcast,需要清空,否则报错“参考的对象类型不支持尝试的操作”; 无需设置SocketOptionName.PacketInformation,在ReceiveMessageFromAsync时会自动设置,并且支持ipv6;
石头 authored at 2024-10-10 00:36:00 石头 committed at 2024-10-10 00:45:43
2.66 KiB
X
using System;
using System.Threading;
using System.Threading.Tasks;
using NewLife.Caching;
using NewLife.Model;
using NewLife.Security;
using Xunit;

namespace XUnitTest.Model
{
    public class HostTests
    {
        [Fact]
        public void TestHost()
        {
            var services = ObjectContainer.Current;

            var redis = new Redis();
            redis.Init("server=127.0.0.1:6379;db=3");
            services.AddSingleton(redis);

            services.AddTransient<RedisService>();
            services.AddTransient<DbService>();

            var host = services.BuildHost();
            host.Add<MyService>();

            // 这里不能长时间阻塞,在应用退出之前,异步不会返回
            //host.Run();
            var task = host.RunAsync();
            task.Wait(3_000);

            var host2 = host as Host;
            Assert.Equal(1, host2.Services.Count);

            var my = host2.Services[0] as MyService;
            Assert.NotNull(my);
            Assert.Equal(99, my.DbCount);
            Assert.True(my.CacheCount > 0);
        }

        private class MyService : IHostedService
        {
            private readonly DbService _dbService;
            private readonly RedisService _redisService;

            public Int32 DbCount => _dbService.Count;
            public Int32 CacheCount => _redisService.Count;

            public MyService(DbService dbService, RedisService redisService)
            {
                _dbService = dbService;
                _redisService = redisService;
            }

            public async Task StartAsync(CancellationToken cancellationToken)
            {
                await Task.Yield();

                _dbService.Init();
                _redisService.InitRedis();
            }

            public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;
        }

        private class DbService
        {
            public Int32 Count { get; set; }

            public void Init()
            {
                // 配置
                var set = NewLife.Setting.Current;
                if (set.IsNew)
                {
                    set.DataPath = "../Data";
                    set.Save();
                }

                //todo 初始化数据库
                Count = 99;
            }
        }

        private class RedisService
        {
            private readonly Redis _redis;

            public Int32 Count { get; set; }

            public RedisService(Redis redis) => _redis = redis;

            public void InitRedis()
            {
                _redis.Set("Name", "Stone", 3600);
                Count = _redis.Count;
            }
        }
    }
}