using Dpz.Core.Web.Jobs.Hubs;
using Microsoft.AspNetCore.SignalR;

namespace Dpz.Core.Web.Jobs.Services.FileTransfer;

/// <summary>
/// 后台服务:每 30 秒清理一次已过期的未配对文件传输房间。
/// </summary>
public sealed class FileTransferRoomCleanupService(
    IFileTransferRoomStore roomStore,
    IHubContext<FileTransferHub> hubContext,
    ILogger<FileTransferRoomCleanupService> logger
) : BackgroundService
{
    /// <summary>
    /// 后台执行逻辑:定时扫描并移除过期房间,通知发起方房间已关闭。
    /// </summary>
    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        using var timer = new PeriodicTimer(TimeSpan.FromSeconds(30));
        try
        {
            while (await timer.WaitForNextTickAsync(stoppingToken))
            {
                var expiredRooms = roomStore.RemoveExpiredPendingRooms(DateTimeOffset.UtcNow);
                foreach (var room in expiredRooms)
                {
                    logger.LogInformation("文件传输房间过期:{RoomKey}", room.Key);
                    await hubContext
                        .Clients.Client(room.InitiatorConnectionId)
                        .SendAsync(
                            "roomExpired",
                            "10 分钟内无人加入,房间已关闭。",
                            cancellationToken: stoppingToken
                        );
                }
            }
        }
        catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) { }
    }
}
评论加载中...