我正在学习 SignalR,需要你的帮助。在下面的代码中,您可以看到我的第一个项目的中心之一。在此中心,我创建一个队列并使用 JoinQueue 方法填充它。现在我正在寻找一种技术,每 5 秒在控制台上打印队列中的成员数量。我想我需要一种方法来管理这个中心之外的队列。
using BackEnd.Model;
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace BackEnd.Hubs
{
public class QueueHub : Hub
{
private Queue<QueueItem> userQueue = new Queue<QueueItem>();
public async Task JoinQueue(string userToken)
{
QueueItem user = new QueueItem
{
UserToken = userToken,
ConnectionString = Context.ConnectionId
};
userQueue.Enqueue(user);
Console.WriteLine(userQueue.Count);
}
public override Task OnConnectedAsync()
{
string connectionId = Context.ConnectionId;
Console.WriteLine($"{connectionId} is Connected to the server");
return base.OnConnectedAsync();
}
}
使用后台服务,可以帮助你实现这个需求。
这是我这边的测试结果。
我的测试项目的结构。
QueueMonitorService.cs
using WebApplication2.IServices;
namespace WebApplication2.BackgroundServices
{
public class QueueMonitorService : BackgroundService
{
private readonly IQueueManager _queueManager;
public QueueMonitorService(IQueueManager queueManager)
{
_queueManager = queueManager;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
Console.WriteLine(DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")+$" The number of members in the queue: {_queueManager?.UserQueue?.Count}");
await Task.Delay(5000, stoppingToken);
}
}
}
}
QueueHub.cs
using Microsoft.AspNetCore.SignalR;
using WebApplication2.IServices;
namespace WebApplication2.Hubs
{
public class QueueHub : Hub
{
private readonly IQueueManager _queueManager;
public QueueHub(IQueueManager queueManager)
{
_queueManager = queueManager;
}
public Task AddToQueue(string userToken)
{
_queueManager.JoinQueue(userToken, Context.ConnectionId);
return Task.CompletedTask;
}
public override Task OnConnectedAsync()
{
string connectionId = Context.ConnectionId;
Console.WriteLine($"{connectionId} is Connected to the server");
return base.OnConnectedAsync();
}
}
}
IQueueManager.cs
using WebApplication2.Models;
namespace WebApplication2.IServices
{
public interface IQueueManager
{
Queue<QueueItem>? UserQueue { get; }
void JoinQueue(string userToken, string connectionId);
}
}
QueueItem.cs
namespace WebApplication2.Models
{
public class QueueItem
{
public string? UserToken { get; set; }
public string? ConnectionString { get; set; }
}
}
QueueManager.cs
using WebApplication2.IServices;
using WebApplication2.Models;
namespace WebApplication2.Services
{
public class QueueManager : IQueueManager
{
public Queue<QueueItem> UserQueue { get; } = new Queue<QueueItem>();
public void JoinQueue(string userToken, string connectionId)
{
QueueItem user = new QueueItem
{
UserToken = userToken,
ConnectionString = connectionId
};
UserQueue.Enqueue(user);
Console.WriteLine(UserQueue.Count);
}
}
}
最后一步,我们需要将其注册到Program.cs文件中。
builder.Services.AddSingleton<IQueueManager, QueueManager>();
builder.Services.AddHostedService<QueueMonitorService>();
builder.Services.AddSignalR();