服务总线应该只存在一次,还是我会创建多个服务总线实例,每个虚拟聊天室一个,并为每个感兴趣的客户订阅一个消息处理程序实例?
使用 NServiceBus 时,您将为您创建的每个 endpoint 配置一个总线。您可以将端点视为处理某些消息的服务。端点不是动态的,它们需要指定一个名称,以便其他端点可以配置为向它们发送消息或从它们接收消息。
这取决于您的系统的要求,但我假设 虚拟聊天室 是您可以动态生成和/或在不再使用时删除的东西。 p>
它是否与我在 Azure 上下文中已经阅读过的主题和订阅的概念有关?
NServiceBus 和 Azure 服务总线都提供了进行发布/订阅的基础结构。
我真的不知道如何设计多个私人上下文,其中一组客户对同一消息的副本感兴趣
多个私有上下文到底是什么意思?我将您的问题理解为如何在客户和聊天室之间建立关系。您的描述中缺少的部分是持久性,即存储客户端和聊天室之间的关系。
以 NServiceBus 为例,您可以有一个 ClientService 来处理有关客户端采取的任何操作的消息,以及一个 ChatroomService 来处理有关聊天室中发生的操作的消息。然后工作流程可以去:
- 客户端进入聊天室(客户端向客户端发送命令)
- ClientService 将信息添加到 Client 对象并对其进行更新(持久性)
- ClientService 向 ChatroomService 发送命令以更新与相应聊天室关联的客户端列表。 (命令)
- 聊天室服务更新订阅客户端列表(持久性)
- 另一个客户端在聊天室中创建了一个
Post。 (客户端向 ClientService 发送命令)
- ClientService 使用新的
Post 和创建它的客户 ID 以及发送到的聊天室 ID(命令)向 ChatroomService 发送命令
- ChatroomService 将
Post 添加到相应聊天室中的Posts 列表中(持久性)
- ChatroomService 为列表中订阅相应聊天室(发布)的所有其他客户端生成事件
- ClientService 处理 ChatroomService 引发的事件并将
Post 分发给其他订阅的客户端。 (订阅)
我实际上并没有创建一个聊天室应用程序,所以这可能不是你的想法的最佳设计,但它提供了一种描述如何使用 NServiceBus 来创建应用程序的方法。您可以使用端点来设置服务,这些端点处理与系统中的对象相对应的消息。通过这种或类似的设计,您可以实现关注点分离,并且可以根据每种对象类型必须处理的流量按需扩展您的服务。
编辑以根据 cmets 中的问题添加更具体的示例
注意:将text message 的所有引用更改为Post,以便在NServiceBus 中chat message 和IMessage 之间没有歧义。我一直在故意使用术语command 和event。在 NServiceBus 中,ICommand 是一种只能发送到一个端点的消息,而IEvent 是一种可以被多个端点发布和订阅的消息。
如果示例不清楚,请致歉。我试图传达的是,您可以存储Clients 和Chatrooms 之间的关系,这样当Chatroom 获得新的Post 时,它可以仅分发给Clients与它有关。假设您有一个聊天室 CR 和 3 个客户 A、B 和 C,它们都在 CR 中。另外,假设我们有以下类:
class Chatroom
{
Guid Id { get; set; }
List<Client> Subscribers { get; set; }
List<Posts> Posts { get; set; }
}
class Client
{
Guid Id { get; set; }
List<Chatroom> Chatrooms { get; set; }
ConnectionInfo Info { get; set; }
}
class Post
{
Guid Id { get; set; }
Guid ClientId { get; set; }
Guid ChatroomId { get; set; }
string Text { get; set; }
}
class NewPostCommand : ICommand
{
Post NewPost { get; set; }
}
class NewChatroomPostEvent : IEvent
{
Post NewPost { get; set; }
Chatroom Chatroom { get; set; }
List<Client> Subscribers { get; set; }
}
-
A 创建一个 Post 到 CR,这是使用从客户端到 API 的 HTTP 调用来实现的。 API 是用作 ClientService 的 NServiceBus 服务的一部分。 API 调用会创建一个 Post,其中包含文本 A.Id 和 CR.Id。
- ClientService 使用刚刚创建的
Post 向ChatroomService 发送NewPostCommand。
- ChatroomService 接收
NewPostCommand 并将其传递给相应的处理程序。
- 处理程序使用
Post 上的ChatroomId 在您的数据库中搜索相应的Chatroom (CR)。新的Post 被添加到CR.Posts 并更新数据库。
- Handler 从
CR 中获取CR.Clients 减去Post.ClientId 的列表(导致B 和C)。
- 处理程序发布一个新的
NewChatroomPostEvent,其中包含Post、Chatroom 和Subscribers。
- ClientService 订阅
NewChatroomPostEvent,接收消息并将其传递给相应的处理程序。
- ClientService 具有与客户端通信的所有功能(使用
Client.Info)并将新的Post 发送到NewChatroomPostEvent.Subscribers 列表中的每个客户端(B 和C)。
现在我们已经了解了新帖子的消息流,您可以想象如何处理在每个聊天室中添加和删除订阅者。客户端在进入或离开聊天室时会向 HTTP API 发送消息,ClientService 会向 ChatroomService 发送消息,后者将更新相应的Chatroom.Subscribers 列表。希望这能阐明您如何控制在新帖子到达时向哪些客户端发送更新。