Distributed architecture with MassTransit, RabbitM

2019-04-05 14:06发布

问题:

I'm developing distributed application with help of MassTransit and rabbitmq

I have to provide ability to generate report on a web page without page reloading by click on a button, also I should call a windows service for data preparation (The service handles each request for 30sek - 1min).

My first try based on this sample: https://github.com/MassTransit/Sample-RequestResponse

    [HttpPost]
    public async Task<HttpStatusCodeResult> GenerateReport(string someJsonData)
    {    
        var serviceAddress = new Uri(ConfigurationManager.AppSettings["BaseLineRecordService"]);
        var client = this.Bus.CreateRequestClient<ICreateReportRequest, ICreateReportResponse>(serviceAddress, TimeSpan.FromHours(1));
        ICreateReportResponse response = await client.Request(new CreateReportRequest());
        reportHub.ShowRepordData(response); // Update data by SingleR
        return new HttpStatusCodeResult(200);
    }

But as I understand it' not a better approach, because I'm keeping connection during all data preparation.

I've read many articles and I have found three ways. Which way is preferred?

1) Like on this article http://www.maldworth.com/2015/07/19/signalrchat-with-masstransit-v3/

2) As first but with Rest API calling instead of Consumers from IIS side

3) Idea from this article http://weblog.west-wind.com/posts/2013/Sep/04/SelfHosting-SignalR-in-a-Windows-Service

回答1:

I do this using hubs from SignalR, and observe events at the server using regular MassTransit consumers. When events are observed, I trigger the event handler, which dispatches using the Hub to connected clients. That way, the events are pushed down to the browser instantly without leaving an async call pending at the server in a controller.

You can see this in Fooidity which does something similar:

https://github.com/phatboyg/Fooidity/blob/develop/src/Fooidity.Management.Web/Hubs/ApplicationHubEventHandler.cs#L18

Using the GlobalHost to resolve the Hub, then raising the method on the hub. The event context can be discriminated by using groups, which are a SignalR feature that is handled per node. So as long as every node is observing the event, clients can be connected to any hub and get notified. This works nicely for load balancing, without having to use a heavy cluster backplane for SignalR -- since RabbitMQ is super lightweight for event distribution.

You can do it with non-durable queues as well, which makes it even faster -- since a server reset/connection drop is more likely than a broker crash.

Authentication is handled inside the ApplicationHub, as shown in the adjacent source file: https://github.com/phatboyg/Fooidity/blob/develop/src/Fooidity.Management.Web/Hubs/ApplicationHub.cs

Check it out, hopefully it helps.