MassTransit saga / statemachine没有将请求响应返回给控制器

我觉得我已经接近这个工作但似乎无法让它超越线路……

我有一个带有saga /状态机的.NET核心ASP应用程序,似乎在大多数情况下运行良好。 它:

  1. 收到请求
  2. 发布由路由单拾取的事件
  3. 当路由单完成时,它会发布一个事件
  4. 这个事件被传染了
  5. 然后,saga将请求发送给请求/响应使用者
  6. 响应回到了传奇
  7. 然后,然后我使用RespondAsync尝试将响应发送回原始呼叫控制器但是没有任何回复

我的控制器看起来像:

private readonly IRequestClient _client; public async Task CreateLinkAsync([FromBody]CreateLinkRequest request) { var requestLink = new RequestLink { GroupName = $"{request.Name} Group", Name = request.Name, LinkId = Guid.NewGuid() }; var result = await _client.Request(requestLink).ConfigureAwait(false); return Ok(); } 

我的传奇的减少版本看起来像:

 Request(() => LinkRequest, x => x.RequestId, cfg => { cfg.ServiceAddress = new Uri($"rabbitmq://localhost/request_end_point_name"); cfg.SchedulingServiceAddress = new Uri($"rabbitmq://localhost/request_end_point_name"); cfg.Timeout = TimeSpan.FromSeconds(30); }); During(RequestReceived, When(LinkCreatedEvent) .Request(LinkRequest, context => new SelectUrlByPublicId(context.Data.DatabaseId, context.Data.LinkId)) .TransitionTo(LinkRequest.Pending)); During(LinkRequest.Pending, When(LinkRequest.Completed) .ThenAsync(context => context.RespondAsync(new RequestLinkCompleted { CorrelationId = LinkRequest.GetRequestId(context.Instance), DatabaseId = context.Data.DatabaseId })) .Finalize()); 

最后在我的启动代码中,我按如下方式配置请求/响应:

 services.AddScoped<IRequestClient>(x => new MessageRequestClient(_bus, new Uri($"{messageBusSettings.Host}/create_link_saga"), TimeSpan.FromSeconds(30))); 

我猜测RespondAsync调用没有使用正确/原始的requestId,但我不知道如何检查或更改它。 有人可以帮忙吗?

由于原始请求的上下文丢失,您需要自己完成在RespondAsync中所做的事情。

  1. 从请求消息上下文中保存ResponseAddress
  2. 从同一上下文中保存RequestId

在您的传奇中,当需要响应时,您需要使用context.GetSendEndpoint(context.Instance.SavedResponseAddress)然后调用Send设置委托中的RequestId以匹配原始上下文中保存的RequestId。

现在,您可能需要将这些保存在路由滑动变量中,因为您的传奇没有获得命令,只是后续事件,但净效果是相同的,原始请求消息消失了,传奇从未见过。