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");
}
}