MassTransit与RabbitMQ:MT在第二次请求/响应时超时

MassTransit与RabbitMQ:MT在第二次请求/响应时超时,rabbitmq,masstransit,Rabbitmq,Masstransit,使用MassTransit和RabbitMQ处理请求/响应场景。 当执行一个简单的请求/回复时,它会多次工作。 如果我在请求处理程序中发布消息,它将在第一个请求上工作,但请求处理程序在第二个请求上从未被调用,并最终超时,消息将保留在服务器队列中 好像我错过了什么;也许是配置 该项目正在进行中 客户端配置: ObjectFactory.Configure(cfg => { cfg.AddRegistry<WebRegistry>(); cfg.For<ISe

使用MassTransit和RabbitMQ处理请求/响应场景。 当执行一个简单的请求/回复时,它会多次工作。 如果我在请求处理程序中发布消息,它将在第一个请求上工作,但请求处理程序在第二个请求上从未被调用,并最终超时,消息将保留在服务器队列中

好像我错过了什么;也许是配置

该项目正在进行中

客户端配置:

ObjectFactory.Configure(cfg =>
{
    cfg.AddRegistry<WebRegistry>();
    cfg.For<IServiceBus>().Singleton().Use(o => ServiceBusFactory.New(sbc =>
    {
        // configure the bus
        sbc.UseRabbitMqRouting();
        sbc.ReceiveFrom("rabbitmq://localhost/entrprise_client");

        // finds all the consumers in the container and register them with the bus
        sbc.Subscribe(x => x.LoadFrom(ObjectFactory.Container));
    }));
});
var container = new Container(cfg =>
{
    cfg.Scan(scan =>
    {
        scan.Assembly("Server.MessageHandlers");
        scan.AddAllTypesOf<IConsumer>();
    });
});

var bus = ServiceBusFactory.New(sbc =>
{
    // configure the bus
    sbc.UseRabbitMqRouting();
    sbc.ReceiveFrom("rabbitmq://localhost/enterprise_server");

    // finds all the consumers in the container and register them with the bus
    sbc.Subscribe(x => x.LoadFrom(container));
});

// finally inject the bus into the container
container.Inject(bus);
ObjectFactory.Configure(cfg=>
{
cfg.AddRegistry();
cfg.For().Singleton().Use(o=>ServiceBusFactory.New(sbc=>
{
//配置总线
sbc.UseRabbitMqRouting();
sbc.从(”rabbitmq://localhost/entrprise_client");
//查找容器中的所有使用者,并向总线注册它们
Subscribe(x=>x.LoadFrom(ObjectFactory.Container));
}));
});
服务器配置:

ObjectFactory.Configure(cfg =>
{
    cfg.AddRegistry<WebRegistry>();
    cfg.For<IServiceBus>().Singleton().Use(o => ServiceBusFactory.New(sbc =>
    {
        // configure the bus
        sbc.UseRabbitMqRouting();
        sbc.ReceiveFrom("rabbitmq://localhost/entrprise_client");

        // finds all the consumers in the container and register them with the bus
        sbc.Subscribe(x => x.LoadFrom(ObjectFactory.Container));
    }));
});
var container = new Container(cfg =>
{
    cfg.Scan(scan =>
    {
        scan.Assembly("Server.MessageHandlers");
        scan.AddAllTypesOf<IConsumer>();
    });
});

var bus = ServiceBusFactory.New(sbc =>
{
    // configure the bus
    sbc.UseRabbitMqRouting();
    sbc.ReceiveFrom("rabbitmq://localhost/enterprise_server");

    // finds all the consumers in the container and register them with the bus
    sbc.Subscribe(x => x.LoadFrom(container));
});

// finally inject the bus into the container
container.Inject(bus);
var容器=新容器(cfg=>
{
扫描(扫描=>
{
scan.Assembly(“Server.MessageHandlers”);
scan.AddAllTypesOf();
});
});
var bus=ServiceBusFactory.New(sbc=>
{
//配置总线
sbc.UseRabbitMqRouting();
sbc.从(”rabbitmq://localhost/enterprise_server");
//查找容器中的所有使用者,并向总线注册它们
Subscribe(x=>x.LoadFrom(container));
});
//最后将总线注入容器中
容器.注射(公共汽车);
发送请求:

bus.PublishRequest(new CreateProductCommand(correlationId, model.Name, model.Description, model.Price), x =>
{
    x.HandleTimeout(10.Seconds(), () => { timedOut = true; });
    x.Handle<CreateProductCommand.Response>(response => { productId = response.Id; });
});
public void Consume(IConsumeContext<CreateProductCommand> context)
{
    Console.Out.WriteLine("Consuming Create Product");

    // simulate creating a product
    var productId = "products/1234";

    bus.Publish(new ProductCreatedEvent(productId));

    context.Respond(new CreateProductCommand.Response(context.Message.CorrelationId) { Id = productId});
}
bus.PublishRequest(新的CreateProductCommand(correlationId、model.Name、model.Description、model.Price),x=>
{
x、 HandleTimeout(10.Seconds(),()=>{timedOut=true;});
x、 句柄(response=>{productId=response.Id;});
});
正在使用请求:

bus.PublishRequest(new CreateProductCommand(correlationId, model.Name, model.Description, model.Price), x =>
{
    x.HandleTimeout(10.Seconds(), () => { timedOut = true; });
    x.Handle<CreateProductCommand.Response>(response => { productId = response.Id; });
});
public void Consume(IConsumeContext<CreateProductCommand> context)
{
    Console.Out.WriteLine("Consuming Create Product");

    // simulate creating a product
    var productId = "products/1234";

    bus.Publish(new ProductCreatedEvent(productId));

    context.Respond(new CreateProductCommand.Response(context.Message.CorrelationId) { Id = productId});
}
public void消费(IConsumeContext上下文)
{
Console.Out.WriteLine(“消费创建产品”);
//模拟创建产品
var productId=“products/1234”;
发布(新ProductCreatedEvent(productId));
Respond(新的CreateProductCommand.Response(context.Message.CorrelationId){Id=productId});
}
信息:

public class CreateProductCommand : CorrelatedBy<Guid>
{
    public Guid CorrelationId { get; private set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }

    public CreateProductCommand(Guid correlationId, string name, string description, decimal price) 
    {
        CorrelationId = correlationId;
        Name = name;
        Description = description;
        Price = price;
    }

    public class Response : CorrelatedBy<Guid>
    {
        public Guid CorrelationId { get; private set; }

        public string Id { get; set; }

        public Response(Guid correlationId)
        {
            CorrelationId = correlationId;
        }
    }
}
公共类CreateProductCommand:CorrelatedBy
{
公共Guid CorrelationId{get;private set;}
公共字符串名称{get;set;}
公共字符串说明{get;set;}
公共十进制价格{get;set;}
public CreateProductCommand(Guid correlationId、字符串名称、字符串描述、十进制价格)
{
CorrelationId=CorrelationId;
名称=名称;
描述=描述;
价格=价格;
}
公共类响应:CorrelatedBy
{
公共Guid CorrelationId{get;private set;}
公共字符串Id{get;set;}
公共响应(Guid correlationId)
{
CorrelationId=CorrelationId;
}
}
}

我知道你想在RabbitMQ上使用MT,我放弃了,把我的爱转向EasyNetQ,试试看(-:

我知道你想在RabbitMQ上使用MT,我放弃了,把我的爱转向EasyNetQ,试试看(-:

感谢Chris建议在IConsumeContext上使用总线。这似乎已经解决了问题

因此,您不需要在处理程序的构造函数中注入IServiceBus,而是从上下文中获取总线

public class CreateProductCommandHandler : Consumes<CreateProductCommand>.Context
{
    public void Consume(IConsumeContext<CreateProductCommand> context)
    {
        Console.Out.WriteLine("Consuming Create Product");

        // simulate creating a product
        var productId = "products/1234";

        context.Bus.Publish(new ProductCreatedEvent(productId));

        context.Respond(new CreateProductCommand.Response(context.Message.CorrelationId) { Id = productId});
    }
}
公共类CreateProductCommandHandler:Consumes.Context
{
公共void消费(IConsumeContext上下文)
{
Console.Out.WriteLine(“消费创建产品”);
//模拟创建产品
var productId=“products/1234”;
Publish(新的ProductCreatedEvent(productId));
Respond(新的CreateProductCommand.Response(context.Message.CorrelationId){Id=productId});
}
}

感谢Chris建议使用IConsumeContext上的总线。这似乎已经解决了问题

因此,您不需要在处理程序的构造函数中注入IServiceBus,而是从上下文中获取总线

public class CreateProductCommandHandler : Consumes<CreateProductCommand>.Context
{
    public void Consume(IConsumeContext<CreateProductCommand> context)
    {
        Console.Out.WriteLine("Consuming Create Product");

        // simulate creating a product
        var productId = "products/1234";

        context.Bus.Publish(new ProductCreatedEvent(productId));

        context.Respond(new CreateProductCommand.Response(context.Message.CorrelationId) { Id = productId});
    }
}
公共类CreateProductCommandHandler:Consumes.Context
{
公共void消费(IConsumeContext上下文)
{
Console.Out.WriteLine(“消费创建产品”);
//模拟创建产品
var productId=“products/1234”;
Publish(新的ProductCreatedEvent(productId));
Respond(新的CreateProductCommand.Response(context.Message.CorrelationId){Id=productId});
}
}

我不确定快速查看这个问题的解决方案。我建议加入我们的邮件列表,以便其他人可以参与查看。还包括您使用的MT版本。此外,打开日志记录并验证没有引发异常。我想知道容器是否在fi之后处理总线实例rst消息已被使用。您可以作为IConsumeContext上的属性访问总线,因此不需要在使用者构造函数中依赖它。启用日志记录,并且除了在第二次发布时抛出的超时之外,没有看到任何其他错误。在consumeContext上使用总线,这似乎可以修复它。我不确定解决方法我只是快速看一下。我建议加入我们的邮件列表,以便其他人可以站出来查看。还包括您正在使用的MT版本。此外,打开日志记录并验证没有引发异常。我想知道在第一条消息被使用后,容器是否正在处理总线实例。您可以作为IConsumeContext上的属性访问总线,因此不需要在使用者构造函数中依赖它。启用了日志记录,并且除了在第二次发布时引发的超时之外,没有看到任何其他错误。在consumeContext上使用了总线,这似乎可以修复它。