REBUS 在队列中发送消息,并在另一个应用程序中接收
REBUS Send message in Queue ,and receive in another application
我想使用 rebus 实现以下场景。我正在创建发件人应用程序和一个接收应用程序。会有一个class假设
public class GetPersonRequest
{
public int Id { get; set; }
public string Name { get; set; }
}
public class GetPersonResponse
{
public int Id { get; set; }
public string Name { get; set; }
}
我将在队列中发送此 class 对象及其值。并希望在接收器中显示这些值。如何实现?
SENDER 代码如下:
static void Main(string[] args)
{
GetPersonRequest objGetPersonRequest = new GetPersonRequest();
objGetPersonRequest.Id = 12;
objGetPersonRequest.Name = "Kumar";
using (var activator = new BuiltinHandlerActivator())
{
activator.Register(() => new PrintName());
var bus = Configure.With(activator)
.Logging(l => l.None())
.Transport(t => t.UseMsmq("rebus-application.input"))
.Routing(r => r.TypeBased().Map<GetPersonRequest>("rebus.application.output"))
.Start();
bus.Send(objGetPersonRequest);
Console.WriteLine("Press enter to quit");
Console.ReadLine();
}
RECEIVER 在另一个控制台应用程序中这样的代码:
static void Main(string[] args)
{
using (var activator = new BuiltinHandlerActivator())
{
activator.Register(() => new PrintName());
var bus = Configure.With(activator)
.Logging(l => l.None())
.Transport(t => t.UseMsmq("rebus-application.output"))
.Routing(r => r.TypeBased().Map<GetPersonResponse>("rebus-application.input"))
.Start();
Console.WriteLine("Press enter to quit");
Console.ReadLine();
}
}
class PrintName : IHandleMessages<GetPersonResponse>
{
public async Task Handle(GetPersonResponse objGetPersonResponse)
{
Console.WriteLine("RebusDetails Name is {0}", objGetPersonResponse.Name);
}
}
如何实现?
我建议您看一下 the request/reply sample from the RebusSamples repository - 它显示了正确执行 request/reply.
所需的配置
通过快速浏览您的代码,我可以看到以下内容 issues/misunderstandings:
- Rebus 方法是异步的,因此
bus.Send(objGetPersonRequest)
将在另一个线程上执行,您不会知道它是否失败 - 总是 await bus.Send(...)
或 bus.Send(...).Wait()
- 在许多情况下,只有 "clients" (*) 应该有端点映射 - 在您的情况下,您应该将
GetPersonRequest
(或者可能包含它的整个程序集?)映射到 rebus.application.output
,然后在处理程序中执行 await bus.Reply(new GetPersonResponse(...))
- 这样,"server"(*) 将没有任何依赖关系
此外 - 这可能是一个细节,但我认为随着时间的推移它会导致更好的理解和更容易的沟通:
- 没有 "output queue" 这样的东西 - 所有队列都是端点的输入队列,端点将其作为输入队列 - 因此,我认为
rebus-application.output
这个名称具有误导性
- 我建议您将队列名称更改为能够更好地标识每个端点的名称,例如由于您的服务器似乎能够返回一个人的详细信息,因此您可以将其称为
masterdata
、crm
等,如果您使用 .input
等后缀,则可能是希望每个端点都有一个错误队列(例如 masterdata.input
和 masterdata.error
)。
我希望这是有道理的:)
(*) 根据我的经验,明确区分端点的客户端和服务器角色是有益的,其中客户端是没有(或很少)afferent couplings 的端点,这允许它们很容易成为 added/removed/changed,并且服务器是具有更多传入耦合的端点。
当您从服务器 await bus.Reply(...)
时,它允许发件人保持客户端状态,而不是在任何地方配置其端点地址,而是在其自己的配置中。
我想使用 rebus 实现以下场景。我正在创建发件人应用程序和一个接收应用程序。会有一个class假设
public class GetPersonRequest
{
public int Id { get; set; }
public string Name { get; set; }
}
public class GetPersonResponse
{
public int Id { get; set; }
public string Name { get; set; }
}
我将在队列中发送此 class 对象及其值。并希望在接收器中显示这些值。如何实现?
SENDER 代码如下:
static void Main(string[] args)
{
GetPersonRequest objGetPersonRequest = new GetPersonRequest();
objGetPersonRequest.Id = 12;
objGetPersonRequest.Name = "Kumar";
using (var activator = new BuiltinHandlerActivator())
{
activator.Register(() => new PrintName());
var bus = Configure.With(activator)
.Logging(l => l.None())
.Transport(t => t.UseMsmq("rebus-application.input"))
.Routing(r => r.TypeBased().Map<GetPersonRequest>("rebus.application.output"))
.Start();
bus.Send(objGetPersonRequest);
Console.WriteLine("Press enter to quit");
Console.ReadLine();
}
RECEIVER 在另一个控制台应用程序中这样的代码:
static void Main(string[] args)
{
using (var activator = new BuiltinHandlerActivator())
{
activator.Register(() => new PrintName());
var bus = Configure.With(activator)
.Logging(l => l.None())
.Transport(t => t.UseMsmq("rebus-application.output"))
.Routing(r => r.TypeBased().Map<GetPersonResponse>("rebus-application.input"))
.Start();
Console.WriteLine("Press enter to quit");
Console.ReadLine();
}
}
class PrintName : IHandleMessages<GetPersonResponse>
{
public async Task Handle(GetPersonResponse objGetPersonResponse)
{
Console.WriteLine("RebusDetails Name is {0}", objGetPersonResponse.Name);
}
}
如何实现?
我建议您看一下 the request/reply sample from the RebusSamples repository - 它显示了正确执行 request/reply.
所需的配置通过快速浏览您的代码,我可以看到以下内容 issues/misunderstandings:
- Rebus 方法是异步的,因此
bus.Send(objGetPersonRequest)
将在另一个线程上执行,您不会知道它是否失败 - 总是await bus.Send(...)
或bus.Send(...).Wait()
- 在许多情况下,只有 "clients" (*) 应该有端点映射 - 在您的情况下,您应该将
GetPersonRequest
(或者可能包含它的整个程序集?)映射到rebus.application.output
,然后在处理程序中执行await bus.Reply(new GetPersonResponse(...))
- 这样,"server"(*) 将没有任何依赖关系
此外 - 这可能是一个细节,但我认为随着时间的推移它会导致更好的理解和更容易的沟通:
- 没有 "output queue" 这样的东西 - 所有队列都是端点的输入队列,端点将其作为输入队列 - 因此,我认为
rebus-application.output
这个名称具有误导性 - 我建议您将队列名称更改为能够更好地标识每个端点的名称,例如由于您的服务器似乎能够返回一个人的详细信息,因此您可以将其称为
masterdata
、crm
等,如果您使用.input
等后缀,则可能是希望每个端点都有一个错误队列(例如masterdata.input
和masterdata.error
)。
我希望这是有道理的:)
(*) 根据我的经验,明确区分端点的客户端和服务器角色是有益的,其中客户端是没有(或很少)afferent couplings 的端点,这允许它们很容易成为 added/removed/changed,并且服务器是具有更多传入耦合的端点。
当您从服务器 await bus.Reply(...)
时,它允许发件人保持客户端状态,而不是在任何地方配置其端点地址,而是在其自己的配置中。