Trying to follow the documentation I would like to send a message to the user's destination and subscribe to it from a browser. The full demo is available here but basically I have
@MessageMapping("/private-message")
@SendToUser("/queue/messages")
fun addUser(
@Payload chatMessage: String,
principal: Principal
): String {
logger.info("Received message: $chatMessage from user: ${principal.name}")
return "Hello, ${principal.name}! You sent: $chatMessage"
}
...
@Bean
fun messageAuthorizationManager(
messages: MessageMatcherDelegatingAuthorizationManager.Builder
): AuthorizationManager<Message<*>> {
val tokenAuthorizationManager = AuthorizationManager<MessageAuthorizationContext<*>> { auth, context ->
authenticateAndAuthorize(auth.get(), context.message)
}
messages
.simpTypeMatchers(SimpMessageType.CONNECT, SimpMessageType.DISCONNECT).permitAll()
.simpDestMatchers("/app/status", "/topic/status").permitAll()
.anyMessage().access(tokenAuthorizationManager)
return messages.build()
}
And the following frontend to call it
<StompClient
title={`Private Chat - ${username}`}
subscribeTopic={`/user/${username}/queue/messages`}
publishTopic="/app/private-message"
onError={(error) => console.error('Private chat error:', error)}
/>
...
const subscribeToTopic = (stompClient) => {
if (!stompClient?.active) return;
try {
stompClient.subscribe(
subscribeTopic,
(message) => {
const messageText = message.body.replace(/^Status:\s*/, "");
setMessages((prev) => [...prev, messageText]);
},
{
"Authorization": `Bearer test.token`
});
} catch (err) {
handleError(`Failed to subscribe: ${err.message}`);
}
};
Most things seem to work, like the username is correct but I can't subscribe to the /user/fakeUser/queue/messages
endpoint. I can see the UserDestinationMessageHandler trying to send the message to the proper simpDestination
. What doesn't the subscription seem to work? I can see by a debug breakpoint I can send a message to /app/private-message.