Home > Mobile >  How to get delayed response with SignalR (Controller calls Background Service)?
How to get delayed response with SignalR (Controller calls Background Service)?

Time:10-09

I read documentation and tutorials about SignalR. But I don't understand how to get response in my situation.

.Net5.

Reactjs sends request to Controller.

Controller action:

[HttpGet("compared")]
public async Task<ActionResult> GetComparedText([FromQuery] PrevDraftVersionDto dto) =>
            Ok(await _mediator.Send(new GetComparedTextQuery(dto.InitialDraftId, dto.DraftId, dto.CurrVer, dto.PrevVer)));

GetComparedTextHandler

public class GetComparedTextHandler : IRequestHandler<GetComparedTextQuery, ComparedDraftDto>
    {
        private readonly AppDbContext _appDbContext;
        private readonly TpaChannel _tpaChannel;

        public GetComparedTextHandler(AppDbContext appDbContext, TpaChannel tpaChannel)
        {
            _appDbContext = appDbContext;
            _tpaChannel = tpaChannel;
        }

 public async Task<ComparedDraftDto> Handle(GetComparedTextQuery request, CancellationToken cancellationToken)
{
   var edDraftComparison = ...// get compared text from repository
   if (edDraftComparison == null) {
      Repository doesn't have record yet.

   // 1) Adding to repository request.InitialDraftId, request.DraftId
   .........

  // 2) Create Channel for background Service
   message = "added_to_queue";
                var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                cts.CancelAfter(TimeSpan.FromSeconds(180)); // wait max  seconds
                var versionDto = new VersionDto(request.InitialDraftId, request.DraftId, request.CurrVer, request.PrevVer);
                await _tpaChannel.AddVersionsAsync(versionDto, cts.Token);

} // if (edDraftComparison == null)
else {...}
return ....
}

Handler sends response to Controller and to web client. But after all tpaChannel start Background Service. It updated a record (by InitialDraftId) in repository.

And then I need to get updated record with SignalR.

I read tutorials, that Controller action can load signalR:

hubContext.Clients.User(UserId).SendAsync(
            "receiveUpdatedText",
            new Article<LikeRelatedPayload>
            {
                DraftId = draftId,
                Payload = payload
            }
        );

But it is wrong idea, because, I have to get record from repository after Background Service job.

Where I need to create a singnalR service, that it will send record from Background Service to current user?

Sorry for language, it is difficult for me to explain situation in English.

CodePudding user response:

How about make use of IHubContext in your corresponding background service. I don't know what our background service look like... so I'll just describe some dummy one

public abstract class DummyProcessor : Microsoft.Extensions.Hosting.BackgroundService
{
    IHubContext<MyHub> _myHub;

    protected DummyProcessor(IHubContext<MyHub> myHub)
    {
        ServiceScopeFactory = serviceScopeFactory;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        // some logic...
        await _myHub.Clients.All.SendAsync("As we usually do");
    }
}
  • Related