您如何使用他们自己的用户应用程序实例为多个用户实施对话组,但将相关消息发送到服务代理队列?这种实现有什么好的例子吗?原以为可以自己设置对话组ID,保证各个用户的某组消息是相关的,但是好像这个值会自动生成为UNIQUEIDENTIFIERS...这还是最好的办法吗去做吧?
我想确保捕获并锁定相关消息,例如“同一团队”的两个用户一起竞标同一个项目,以便服务器应用程序逻辑可以一起正确处理这些相关消息(基本上只有第一个将被接受,而第二个将被拒绝,直到用户的视图可以更新,以便他们知道另一个用户已经更改了出价)。
流向是从用户 A、B、C 向队列发送 xml 消息,然后是出队服务,该服务将 xml 发送到外部 Web 服务。我们发送的消息是结构化的 xml 消息,这些消息将在出队后修改外部 Web 服务上不同项目的订单。
谢谢!
如果您正在尝试这样做,您不能使用对话组来排除应用程序实例。如果 Instance A 只需要为 Instance A 接收来自队列的消息,而 Instance B 只需要为 Instance B 接收消息,那么instance A 需要使用 queue A 而 instance B 需要使用 queue B。仅当实例 A 和实例 B 都可以处理任何消息,但您希望将它们排除在并发处理相关消息之外时,才可以使用会话组。每次我看到有人试图预先生成对话组 ID,这个想法总是很糟糕。
更新
发起者无法控制目的地(目标)的会话组。即使 A 和 B 在发起者站点的同一个会话组中,这并不意味着它们在目标站点上是相同的,因为会话组是一个本地概念并且不会随消息一起传播。如果您希望 A 和 B 发送的消息属于目标端的同一对话组,则必须以“相反”的顺序开始对话:目标开始对话并将它们放在一个对话组,然后目标开始在此对话上发送消息。因此,对话就像发送消息的“邀请”,逻辑“目标”充当实际的“发起者”。
更新#2。
从理论上讲,这就是它的工作原理:假设您有 10000 种产品。要执行“反向”模式,当用户想要参与应用程序时,它需要“加入”。因此他开始与服务器进行对话并发送消息“我想加入”(称为“对话 0” ')。服务器通过与每个产品的新用户开始对话来处理此消息. 现在用户有 10000 个对话,它可以发送“出价”。对于产品 A,它使用会话 1,对于产品 B 会话 2 等。当用户 B 想要加入时,它也会开始与服务器的新会话并发送“我想加入”消息。服务器通过与该新用户开始 10000 次对话来响应,每个产品再次对话一次,并确保每个人都在产品的相应组中,因此产品 A 与用户 1 的对话与产品对话在同一组中a 用于用户 2。
现在显然任何人都会认为这个方案是有缺陷的:它需要 number_of_products X number_of_user 对话,它使添加和删除产品变得很痛苦(必须维护所有这些用户对话!)等等。一种替代方法是每次对话多路复用产品。假设服务器只与每个用户开始 10 次对话,并且用户使用与产品 id 的最后一位数字对应的对话(因此产品 1 进入对话 1,但产品 11 或 101 也是如此)。这是更可行的,它需要更少的对话,并且在添加或删除产品时不需要特殊的对话管理。您可能会认为这是一个缺点,因为现在服务器锁定的不是产品 1 的所有消息,而是产品 11 的所有消息、所有 101 等的消息,但请考虑这一点:只有当您有服务器上的处理线程数超过每个用户的会话数。如果您有 5 个线程,那么锁定 1、11、101 无关紧要,其他 4 个线程仍有消息要处理。仅当您有 11 个线程时才重要,因为第 11 个线程没有要处理的内容。
现在我不提倡完全部署这个,我只是指出一些可能性。在大多数情况下,CG 锁定将针对每个用户,而不是每个产品,并且添加使用 CG 锁定以避免每个产品上的并发问题的额外维度有点不正统。
并且不要忘记,在 SSB 中保证顺序的唯一构造是对话。因此,如果用户必须在会话 1 上发送对 A 的出价,然后在会话 2 上发送对 B 的出价,则不能保证在处理B 的出价后会处理对 A的出价。唯一的保证是,如果用户 1 为 A 发送了两次出价,它们将按照发送的顺序进行处理。
此外,如果两个不同的用户为产品 A 发送投标,则无法保证这些投标的处理顺序。但是,如果产品 A 的投标最终出现在相同的 CG 上,则可以保证只有一个“处理器线程”会同时看到用户 1 的投标和用户 2 的投标,但要小心,因为不能保证投标在 RECEIVE 结果集中按照它们被接收的顺序呈现。RECEIVE 仅保证:
但结果中的对话顺序基本上是随机的(由对话句柄顺序驱动,一个 GUID)。
在我忘记之前:请记住,还存在
MOVE CONVERSATION
但依赖 MOVE(而不是直接在正确的 CG 中开始对话)非常容易陷入僵局。