How to get the number of subscriptions to a topic in RabbitMQ

时间:2015-07-28 15:35:27

标签: java rabbitmq stomp spring-websocket

I have a chat application that is build using Spring Websokcets (with STOMP) and the message broker I have used is RabbitMQ.

First I will try to explain the flow little bit. In my application same user can be connected to the websocket server from different devices. To keep the things simple, each user will be subscriber to /topic/{userId}. So when somebody sends a message to user 123, he will be able to see that message in all his devices he is connected from, because I am just sending that message to the destination /topic/{userId}.

My problem is before sending a message to a particular topic, I want to check how many users are connected this topic at this point(this number specifies the number of devices the user logged in from). If this number is 0, I want to send this message to a separate queue.

I have checked this question they look very similar to my problem. But I believe that my problem is even simpler. I just want to find out the number of users, I don't need any information about them.

In the question I mentioned above Brian Clozel mentioned that it's possible to get the information about subscription from RabbitMQ REST API, I have searched about how to do this.

If I want to know the number of users that are subscribed to a topic /topic/123, how do I find it out using RabbitMQ API?

I have also checked this this ticket, and it seems there is added support for this use-case but as far as I understood, it will work only with SimpleMessageBroker. Can somebody clarify If I am correct.

I will be able do this using Application Context Events but this would work only for a single server. In a distributed system this will not work. So I thought getting that information from RabbiMQ is the right way of doing it.

UPDATE

Let me explain more clearly what I am trying to do. Say I am a user with userid 123 and If I am logged in to the site from three devices Laptop1,Laptop2 and Mobile1. Initially all of them will be subscribed to /topic/123 (123 is UserId here).

Basically I want to solve two problems:

1) I don't want to keep the websocket connection open even if the user is inactive, so I close the websocket connection after a certain time of inactivity. In reality even If the mobile is inactive, it should be able to get the notifications, So my app will be pinging a notification server to get the notification(not just messages, any kind of notifications). Now say there is an incoming message for 123, if I know that there are no consumers connected to /topic/123 and if the user 123 has our app installed(somehow I will know this information) I want to send push this message to the notification server so that the mobile app will be able to get the message even if the websocket connection is closed.

2) second problem is, say all three connections (Laptop1,Laptop2,Mobile1) are active and there are incoming messages, I want to show notification in only one of the active client (as Gmail or Facebook does). If there is an incoming message to a client and if it knows that there are more than one devices(I can send this information from server) subscribed to /topic/123, at the client side I can decide whether to show the pop-up or not.

1 个答案:

答案 0 :(得分:0)

鉴于您在应用程序中需要的功能,您需要在RabbitMQ前面提供一些东西 - 一个可以托管您的websockets的Web服务器或其他应用程序服务器,并提供所需的逻辑。

RabbitMQ将根据路由键将消息传递到队列。连接到队列的任何消费者都有机会接收消息。如果有多个消费者连接到队列,RabbitMQ会将消息循环到消费者。除非您在给定队列中只有1个消费者,否则无法保证特定消费者将收到特定消息。

仅向单个连接设备发送通知的需要意味着设备列表的优先顺序 - 哪一个更重要并且应该接收通知。根据您的要求,优先顺序似乎是动态的...用户在给定设备上的活跃程度将改变该设备是否应该接收通知。

这种类型的逻辑在RabbitMQ中是不可能直接实现的。

我建议构建一个位于RabbitMQ前面的Web服务器,并让所有设备连接到该Web服务器。使用Web服务器来简化Web套接字,并让Web服务器跟踪给定用户最活跃的设备。 Web服务器可以使用该知识来确定哪个设备接收通知。