zyro23 / grails-spring-websocket

93 stars 28 forks source link

Ho do I get list of subscribed users in a particular topic? #53

Closed ChiranjibKarn closed 6 years ago

ChiranjibKarn commented 6 years ago

This is more of a question rather than an issue, can I get list of users subscribed to a particular topic, from grails controller or service? I have gone through Issue, but could not find a way out.

zyro23 commented 6 years ago

check https://github.com/spring-projects/spring-framework/commit/281588d7bb9b4c15e72d743f5d88cc5ff39ff2de which is mentioned in your referenced issue.

you should be able to autowire the userRegistry and use findSubscriptions (https://docs.spring.io/spring-framework/docs/4.2.4.RELEASE/javadoc-api/org/springframework/web/socket/messaging/DefaultSimpUserRegistry.html#findSubscriptions-org.springframework.messaging.simp.user.SimpSubscriptionMatcher-), e.g.

@Autowired
SimpUserRegistry userRegistry

void findThem() {
    userRegistry.findSubscriptions {
        it.destination == "/topic/myTopic"
    }.each {
        println it.session.user.name
    }
}
ChiranjibKarn commented 6 years ago

We are using DefaultSimpUserRegistry, and it is showing an empty array. Am I missing something?

zyro23 commented 6 years ago

you need an authenticated user, of course. just verified with the readme sample and it works. referencing sample repo any minute.

ChiranjibKarn commented 6 years ago

We are using Grails 3.2.11 REST application and authenticating users using spring-security-rest:2.0.0.M2. We are not re-authenticating users for incoming/outgoing WS messages. So, I need a way to get all subscribed users for a particular topics. It seems, spring-websocket is keeping track of non-authenticated users also in session (I can see it in subscribe event).

zyro23 commented 6 years ago

then you may want to take a look at the SubscriptionRegistry. but that works with Messages, which means you may have to construct a dummy one to find the matching subscriptions.

why do you not authenticate the users properly for this use-case, too? i think as far as the spring websocket support is concerned, it "just" uses the current requests' principal, i.e. request.userPrincipal.name - so that is not even tied to spring security per se.

one way or the other, that allows you to get your subscriptions...

ChiranjibKarn commented 6 years ago

Actually I do not want to put any overhead by authenticating users as I know those WS endpoints are only available for already logged-in users (authenticated by spring-security-rest plugin) and which is good for me now.

And, I do not know how to use SubscriptionRegistry in Grails controller/service, I tried it by injecting it in a service, but that did not work.

Since I do not see any straight forward way to get this list, I am planning to maintain it from our end only.

ajayshah1992 commented 6 years ago

zyro23 I had too have same issue. Can you explain how can we make dummy Message for a particular topic .So that we can get users subscribed on this path.

zyro23 commented 6 years ago

from the subscriptionRegistry, you will only get a

a MultiValueMap with sessionId-subscriptionId pairs, possibly empty.

(https://docs.spring.io/spring/docs/4.2.4.RELEASE/javadoc-api/org/springframework/messaging/simp/broker/SubscriptionRegistry.html#findSubscriptions-org.springframework.messaging.Message-)

then, you have a websocket session id but still no user (as the session cannot be mapped to a user if there was no authentication at the time of session creation).

why is supplying a proper authentication with the websocket subscription request a problem? tbh i do not see that as "overhead" as it is (likely) also relevant for your application security.

zyro23 commented 6 years ago

closing due to inactivity

fr1nkenstein commented 1 year ago

@zyro23 can you guide how to authenicate the user and add in Principal so that i can get data from simpuserRegistory