【发布时间】:2015-07-28 15:35:27
【问题描述】:
我有一个使用Spring Websokcets (with STOMP) 构建的聊天应用程序,我使用的消息代理是RabbitMQ。
首先,我将尝试稍微解释一下流程。在我的应用程序中,同一用户可以从不同的设备连接到 websocket 服务器。为了简单起见,每个用户都将订阅/topic/{userId}。因此,当有人向用户123 发送消息时,他将能够在他连接的所有设备中看到该消息,因为我只是将该消息发送到目标/topic/{userId}。
我的问题是在向特定topic 发送消息之前,我想检查此时topic 连接了多少用户(此数字指定用户登录的设备数量)。如果这个号码是0,我想把这条消息发送到一个单独的队列中。
我检查了this 问题,它们看起来与我的问题非常相似。但我相信我的问题更简单。我只是想知道用户的数量,我不需要任何关于他们的信息。
在我上面提到的问题中,Brian Clozel 提到可以从 RabbitMQ REST API 获取有关订阅的信息,我已经搜索了如何做到这一点。
如果我想知道订阅主题/topic/123的用户数,如何使用 RabbitMQ API 找到?
我还检查了这张this 票,似乎增加了对这个用例的支持,但据我所知,它只适用于SimpleMessageBroker。如果我是正确的,有人可以澄清一下。
我将能够使用Application Context Events 执行此操作,但这仅适用于单个服务器。在分布式系统中,这是行不通的。所以我认为从RabbiMQ 获取这些信息是正确的做法。
更新
让我更清楚地解释我想要做什么。假设我是userid 123 的用户,如果我从三个设备Laptop1、Laptop2 和Mobile1 登录到该站点。最初,他们都将订阅/topic/123(123 在这里是 UserId)。
基本上我想解决两个问题:
1) 即使用户处于非活动状态,我也不想让 websocket 连接保持打开状态,因此我会在一段时间不活动后关闭 websocket 连接。实际上,即使手机处于非活动状态,它也应该能够获取通知,因此我的应用程序将通过 ping notification server 获取通知(不仅仅是消息,任何类型的通知)。现在说有一条123 的传入消息,如果我知道没有消费者连接到/topic/123 并且如果用户123 安装了我们的应用程序(不知何故我会知道这个信息)我想发送推送这个向notification server 发送消息,这样即使 websocket 连接关闭,移动应用也能收到消息。
2) 第二个问题是,假设所有三个连接 (Laptop1,Laptop2,Mobile1) 都处于活动状态并且有传入消息,我只想在其中一个中显示通知活跃的客户端(就像 Gmail 或 Facebook 一样)。如果有一个传入消息到客户端并且如果它知道有多个设备(我可以从服务器发送此信息)订阅/topic/123,在客户端我可以决定是否显示弹出窗口或不是。
【问题讨论】:
-
你在这里想要完成什么?知道某个特定主题有多少消费者的想法不是你应该做的,我认为......可能有更好的设计,但我需要知道你的意图是什么(不仅仅是 jsut 'send到不同的队列' - 你想把它发送到不同的队列吗?)
-
@DerickBailey 我编辑了问题并试图解释我要解决的问题。如果您认为有更好的方法来解决这些问题,请提出建议。
-
我相信你的程序流逻辑已经和你的消息路由逻辑纠缠在一起了。如果您考虑所需的行为,而较少关注消息流或您认为您的设置可能实现的内容,那么它可能有助于指导您进行正确的设计。 发布者不应该知道或关心订阅者的数量。
-
@theMayer 通常是这样,但是对于这个特定的用例,我认为唯一的方法是拦截应用程序上下文事件或查询 RabbitMQ(不知何故)。如果您觉得有更好的方法,请提出建议。
-
@theMayer 在去推送话题之前,至少我应该知道有没有订阅者在听队列吧?
标签: java rabbitmq stomp spring-websocket