У меня есть клиент, который хочет подписаться на производителя через SignalR
. Проблема в том, что я не знаю, как сконструированы Hubs
или как их можно внедрить в сервис.
Iу моего производителя с бесконечным циклом:
class Producer
{
public string GetMessage()=>this.messages.Dequeue();
private Queue<string>messages=new Queue<string>();
public readonly string ID;
private Task produceTask { get; set;}
private CancellationTokenSource src=new CancellationTokenSource();
public Producer(string id)
{
this.Id=id;
produceTask=Task.Run(this.RunAsync,this.src.Token);
}
public void Stop()=>this.src.Cancel();
private async Task RunAsync()
{
while(true)
{
string data=await ProducingOperation();
this.messages.Enqueue(data);
}
}
}
Этот производитель (ы) внедряется как услуга.
class ProducerService
{
public Dictionary<string,Producer>producers=new Dictionary<string,Producer>()
{
//hardcoded
}
}
Запуск
services.AddSingleton<ProducerService>()
Я не знаю, как перенести мой Hub
на мой Producers
, поскольку я не знаю его жизненный цикл. Мне нужно либо inject
концентратор в ProducerService
, либо другой
class MyHub:Hub
{
private ProducerService service{get;set;}
public async Task SetProducer(string producerId)
{
if(!this.service.producers.TryGetValue(producerId,out Producer producer))
{
throw new NotSupportedException();
}
while(true)
{
string message=producer.GetMessage();
await this.Clients.Client(producerId).InvokeAsync("SendAsync",message);
}
}
}
В приведенном выше примере в классе Producer
я использую Queue
для хранения моих произведенных сообщений, которые позже будут извлечены внутри hub
. Лучшей альтернативой будетчтобы внедрить концентратор в источник, чтобы он автоматически публиковался. Можно ли это сделать?