Skip to content

Expose information about STOMP/WebSocket connections and subscriptions [SPR-12029] #16645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
spring-projects-issues opened this issue Jul 24, 2014 · 11 comments
Assignees
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Kirk Stork opened SPR-12029 and commented

It has been suggested that the reference SO question should be opened up as a discussion here.

OP:

When making something like a chat application using Spring Websockets, it is useful to know who all is subscribed to any given topic. For, e.g. presence data displayed in the clients.

I know that I can implement ApplicationListener and keep my own list of "connected users", but it seems like the library must already be doing this work.

What's the recommended way to get active subscription info from the library directly (and without maintaining my own list in memory or db).


Affects: 4.1 RC1

Reference URL: http://stackoverflow.com/questions/24795340/how-to-find-all-users-subscribed-to-a-topic-in-spring-websockets

Referenced from: commits 281588d

7 votes, 14 watchers

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

ApplicationContext events are a good way to keep track of this and it is their intended purpose. In 4.1 this has also been expanded to include subscribe/unsubscribe events.

Aside from that the simple broker does have a SubscriptionRegistry where all subscriptions are stored. Currently we don't but we could provide public accessor methods there. As for the case of using a STOMP broker relay, we don't keep track of individual subscriptions but simply pass them on.

@spring-projects-issues
Copy link
Collaborator Author

Kirk Stork commented

Thanks, that's a useful explanation.

It probably doesn't make sense for Spring to provide an API to specific relay brokers. But, I think it does make sense for the simple broker to surface subscription or connection info in similar ways as the full featured brokers do (i.e.,by noticing events and also by querying). I think providing public api to inspect the SubscriptionRegistry would be a generally useful thing.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

Yet another option would be to create a component that listens to connect and subscription events, retains and exposes the information. An application could then simply configure this component as a bean. The advantage of this would be that it works with both the simple broker and the broker relay.

@spring-projects-issues
Copy link
Collaborator Author

Brian Clozel commented

Hi Kirk Stork

This issues is actually linked with several others and we're trying to come up with the best design possible here.

Could you in a few words explain your use case? What does your application and why are you trying to get that information?
Would you be happy to get:

  • the subscription strings sent by users "/topic/price.stock.*"
  • or the actual topics (which is very different)

What broker are you using? Are you running your application in a clustered environment? (i.e. do you have several instances of the same application running against the same broker?).

Thanks

@spring-projects-issues
Copy link
Collaborator Author

Kirk Stork commented

Brian,

Well the basic app idea was for chat that is context sensitive. So if a user is "in a room" (i.e. subscribed to a "room" topic), then a feature of the app would also be to indicate things like how many people are currently "in that room", and who they are. So the server needs to be able to look up the users who are subscribed to the topic in some way.

If the app can sign up to hear subscription requests, then it can build it's own presence info table as Rossen suggested -- but it seems like somewhere, something in the framework must already be keeping a database of topics and who's connected to them. I just want to be able to query that info through the spring api (i.e., I don't want to care about the broker if I don't have to -- the broker in use is a deployment configuration, so the app can't count on it being any one particular broker.

I think of each subscription as a channel established for some purpose, and I want to...

  • get a list of "channels" this application is interested in or knows about (user created or server created)
  • given a "channel", list the users connected to it
  • given a user, list all the "channels" that user is connected to
  • send messages to any channel I know about
  • send messages to any user I know about

The initial case was using the built-in broker in a non-clustered environment. For testing and experimenting, this is fine. Of course in production there should be a broker involved, but I haven't gotten that far so I haven't chosen a broker. My app probably wouldn't need to scale up to clustered operation, but that seems like it would be an important use-case in general.

@spring-projects-issues
Copy link
Collaborator Author

Brian Hiles commented

I've got another use case where I have users that have logged in to a server for a set of tasks that apply to their skillsets (server determined as to what tasks fit their skills). Upon someone taking a task or a new task added to the list, a notification is needed to be sent to users who have that task or need that task added to their list. Having a list of all registered subscriptions and then loop through them to apply the filter.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

So just to re-iterate we can easily keep track of subscriptions and make that information available. However subscription destinations can be expressed as a pattern and what patterns look like may vary by broker. In other words we can do all items from Kirk's list above when pattern are not used. If patterns are used however then the second item would require some strategy to resolve destinations against patterns specific to the broker in use. Certainly doable, just trying to find out what suits your needs.

@spring-projects-issues
Copy link
Collaborator Author

Shailesh Vaishampayan commented

Yes, I would love to have this feature. In my case also I am building a chat application where there is a topic which tracks log-in activity. Whenever user logs in he subscribes to topic /topic/logintrakcer and then sends a message to announce that he in online so that other subscribers to the topic can have the update. But he would also like to know who is already online and that can be found out directly by knowing who is subscribed to the topic /topic/logintracker.
Will the solution provide only number or other info about a subscriber as well?

@spring-projects-issues
Copy link
Collaborator Author

Christopher Shannon commented

I would also like to have this feature. It would be very useful to me to have public access to the SubscriptionRegistry in the SimpleBrokerMessageHandler and to be able to look up subscriptions that are already being tracked. For example, querying for subscriptions by either a session id or a destination would come in handy.

Something else that would very nice to have is for the DefaultSubscriptionRegistry that is used in SimpleBrokerMessageHandler to keep track of the associated headers as well. It appears that the registry parses out a few things out of the headers such as subscriptionId, destination, etc but it doesn't keep track of the rest of the headers for later use.

My current use case is that I want to publish a message conditionally to all subscribers on a destination based on the existence of a message header and the header value. (similar to a JMS Message Selector) In this case, it would be necessary to be able to query the SubscriptionRegistry and to iterate over all matching subscriptions and examine the headers to determine if the message should be published.

@spring-projects-issues
Copy link
Collaborator Author

Rossen Stoyanchev commented

I've added support to expose information about connected users through a public API. It includes support for user information across multiple servers. See commit 281588.

It would be great to get some feedback on how well this can be used for specific scenarios!

@spring-projects-issues
Copy link
Collaborator Author

spring-projects-issues commented May 12, 2015

Christopher Shannon commented

Thanks Rossen Stoyanchev, this feature along with #17482 is going to be very helpful.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) type: enhancement A general enhancement
Projects
None yet
Development

No branches or pull requests

2 participants