I'm using WebSocketMessageBrokerConfigurer on Java Spring. I need to print a message on the client side that is subscribed to server every time I send request to this API routes:
@PostMapping("/send-message/{id}")
@PostMapping("/send-message")
Problem IS:
When Im triggering @SendTo method - I get the message, but can't get when using @SendToUser method. It shows nothing except a message that the client is subscribed to the server.
I think Im having troubles with understanding the concept of @SendToUser method.
Please show me how to correctly use the method @SendToUser to send a message to a specific user
Here's my configuration:
package kz.kazatomprom.ekap.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/ws");
registry.setUserDestinationPrefix("/users");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/my-ws")
.setAllowedOriginPatterns("*")
.withSockJS();
}
}
Here's my MessageController class:
@Slf4j
@Controller
@RequiredArgsConstructor
public class MessageController {
@MessageMapping("/private-message")
@SendToUser("/topic/private-messages")
public ResponseMessageDto getPrivateMessage(@Payload String message, Principal principal) {
return new ResponseMessageDto(HtmlUtils.htmlEscape(message));
}
@MessageMapping("/message")
@SendTo("/topic/messages")
public ResponseMessageDto getMessage(String message) throws InterruptedException {
return new ResponseMessageDto(HtmlUtils.htmlEscape(message));
}
}
Here's code where i send message to the client:
@Service
@Component
@RequiredArgsConstructor
public class WebSocketService {
private final SimpMessagingTemplate messagingTemplate;
public void notifyUser(String userId, String message) {
messagingTemplate.convertAndSendToUser(userId, "/topic/private-messages", message);
}
public void notifyFrontend(final String message) {
messagingTemplate.convertAndSend("/topic/messages", message);
}
}
@RestController
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/ws")
public class WebSocketController {
private final WebSocketService webSocketService;
@PostMapping("/send-message/{id}")
public void sendMessage(@PathVariable String id, @RequestParam String message) {
webSocketService.notifyUser(id, message);
}
@PostMapping("/send-message")
public void sendMessage(@RequestParam String message) {
log.info("SEND MESSAGE");
webSocketService.notifyFrontend(message);
}
}
And here's a client code where I'm subscribing to this channels:
<!DOCTYPE html>
<html>
<head>
<title>Real-Time Chat</title>
<script src="https://cdn.jsdelivr.net/npm/sockjs-client/dist/sockjs.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/stompjs/lib/stomp.min.js"></script>
</head>
<body>
<div>
<p id="msg"></p>
</div>
<script>
var socket = new SockJS('http://localhost:8082/my-ws');
var stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
stompClient.subscribe('/user/topic/private-messages', function (message) {
alert(message);
})
stompClient.subscribe('/topic/messages', function (message) {
alert(message);
});
});
</script>
</body>
</html>
