简体   繁体   中英

MassTransit Azure Service Bus Request-Response ASP.NET Core RequestTimeoutException

My goal is to make the communication between two applications (WebAPI and Worker) via MassTransit's Request/Response technique. The problem is that I'm never getting inside the consumer (request client), I'm getting a timeout instead.

I found a similar question already but the answer included a link to a github repository which no longer exists. I also tried following a sample but for some reason most samples are created as console applications which is useless for me since I have two WebAPIs trying to communicate with each other.

Anyway, here's my code:

WebAPI.Startup

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddMassTransit(massTransitConfig =>
        {
            massTransitConfig.UsingAzureServiceBus((ctx, cfg) =>
            {
                cfg.Host("Endpoint=sb://----.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=----");
            });
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

Worker.Startup

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddMassTransit(massTransitConfig =>
        {
            massTransitConfig.UsingAzureServiceBus((ctx, cfg) =>
            {
                cfg.Host("Endpoint=sb://----.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=----");
            });

            massTransitConfig.AddConsumer<CreateScheduleRequestClient>();
        });
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

WebAPI.RequestController

[Route("api/requests")]
public class RequestsController : ControllerBase
{
    private readonly IBus _bus;

    public RequestsController(IBus bus)
    {
        _bus = bus;
    }

    [HttpPost("create-schedule")]
    public async Task<IActionResult> CreateSchedule()
    {
        var client = _bus.CreateRequestClient<CreateScheduleRequest>();
        var response = await client.GetResponse<ScheduleCreatedResponse>(new CreateScheduleRequest());

        return Ok(response.Message.Succeeded);
    }
}

DataTransferObjects.CreateScheduleRequest

public class CreateScheduleRequest
{
    public string CommandName { get; set; }
    public string Cron { get; set; }
}

Worker.RequestClients.CreateScheduleRequestClient

public class CreateScheduleRequestClient : IConsumer<CreateScheduleRequest>
{
    public async Task Consume(ConsumeContext<CreateScheduleRequest> context)
    {
        await context.RespondAsync(new ScheduleCreatedResponse(true));
    }
}

DataTransferObjects.ScheduleCreatedResponse

public class ScheduleCreatedResponse
{
    public bool Succeeded { get; }

    public ScheduleCreatedResponse(bool succeeded)
    {
        Succeeded = succeeded;
    }
}

When I call the only endpoint in the RequestsController , I'm getting MassTransit.RequestTimeoutException: Timeout waiting for response, RequestId: 27f60000-167b-00ff-ea0f-08d8e3a0832e after a short period. I'm not able to verify much more about it, I thought it outght to work out of the box but perhaps I'm missing some parameters when initializing the bus in my Startup classes?

================EDIT================ I changed my code a little with regards to what Chris Patterson suggested and to specify that I'd like to go with the IBus approach. The code still throws the same exception after the change.

First, I'd suggest reviewing the request documentation, in particular the controller example that injects IRequestClient<T> into the controller. That will fix your controller code, which shouldn't be using IBus .

Second, your response should be an actual message type, it can't be true . You need to create a second message contract, such as ScheduleRequestCreated and respond with that message type. Then, your GetResponse would change to

GetResponse<ScheduleRequestCreated>(new CreateScheduleRequest(...))

And your response would be:

RespondAsync(new ScheduleRequestCreated(...))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM