@SendToUser
doesn’t send messages to given path, but convertAndSendToUser()
do. I checked the client side and it subscribes correctly. I expect @SendToUser
in RoomExceptionHandler to send errors when he catches them to /user/queue/errors
, but for some reason it doesn’t.
I have this ExceptionHandler:
@ControllerAdvice
@Controller
public class RoomExceptionHandler {
@MessageExceptionHandler({UserAlreadyJoinedException.class, RoomNotFoundException.class,
UserNotAllowedException.class, IllegalRoomSizeException.class})
@SendToUser("/queue/errors")
public ErrorResponse handleException(RuntimeException exc, Message<?> message) {
HttpStatus status;
if (exc instanceof UserAlreadyJoinedException || exc instanceof IllegalRoomSizeException) {
status = HttpStatus.BAD_REQUEST;
} else if (exc instanceof RoomNotFoundException) {
status = HttpStatus.NOT_FOUND;
} else if (exc instanceof UserNotAllowedException) {
status = HttpStatus.FORBIDDEN;
} else {
status = HttpStatus.INTERNAL_SERVER_ERROR;
}
return ErrorResponse.builder()
.timestamp(LocalDateTime.now())
.status(status.value())
.message(exc.getMessage())
.build();
}
}
I have this Controller:
@Controller
@RequiredArgsConstructor
public class RoomController {
private final RoomService roomService;
private final SimpMessagingTemplate messagingTemplate;
@MessageMapping("/rooms/kickMember/{roomId}/{member}")
@SendTo({"/topic/public", "/topic/public/{roomId}"})
public Room kickMember(@DestinationVariable Long roomId,
@DestinationVariable String member,
@Header("username") String username) {
Room updatedRoom = roomService.kickMember(roomId, member, username);
messagingTemplate.convertAndSendToUser(member, "/queue/notifications", "You have been kicked from the room");
return updatedRoom;
}
}
Client side:
stompClient.subscribe("/user/errors", onErrorReceived);
stompClient.subscribe('/user/' + getUsername() + '/queue/notifications', onNotificationReceived);
And here are my WebSocketConfig:
@Configuration
@EnableWebSocketMessageBroker
@RequiredArgsConstructor
@Slf4j
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final JwtUtils jwtUtils;
private final UserDetailsService userDetailsService;
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
registry.addEndpoint("/ws");
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic", "/queue", "/user");
registry.setUserDestinationPrefix("/user");
registry.setApplicationDestinationPrefixes("/app");
}
}
When I remove "/user"
from registry.enableSimpleBroker("/topic", "/queue", "/user");
in WebSocketConfig, @SendToUser
starts sending messages to /user/queue/errors
correctly, but instead convertAndSendToUser()
stop sending messages to '/user/' + getUsername() + '/queue/notifications'
. I don’t know the reason why and how to make both work.