Controller
#RestController
#RequestMapping
#CrossOrigin(origins = "*")
public class ProductController {
#Autowired
private ProductService productService;
#SendTo("/topic/all")
public List<Product> findAll() {
return productService.findAll();
}
}
WebSocketConfig
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("http://127.0.0.1:5500").withSockJS();
}
Js Code
function connect() {
let stompClient = null;
let socket = new SockJS('http://localhost:8080/ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, (frame) => {
stompClient.subscribe('/topic/all',(response) => {
console.log(JSON.parse(response))
console.log(true)
});
});
}
connect();
hello, this is my small project, my main goal in this project is to show all the products in real time, because when a new product is added by the admin, the same product should be visible to the user. I am using debug stompclient.subscribe not wokring Please help me Thanks
Related
I'm trying to build a chat using SpringBoot and websockets. When I try to connect to the controller I get a 404 in the debugger. What am I doing wrong?
main.js
function connect(event) {
username = document.querySelector('#name').value.trim();
if (username) {
usernamePage.classList.add('hidden');
chatPage.classList.remove('hidden');
var socket = new SockJS('http://localhost:8080/ws');
stompClient = Stomp.over(socket);
stompClient.connect({}, onConnected, onError);
}
event.preventDefault();
}
WebSocketConfig.java
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
}
}
I am not able to get my WS working. I wrote this test and it is still failing when I use simpMessagingTemplate but when I use stompSession.send it works. Could anyone help me where I am making mistake?
The problem is NOT in the test PROBABLY, I am not able to make simpMessagingTemplate working in any service.
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#ExtendWith(MockitoExtension.class)
public class WebSocketSpec {
#LocalServerPort
private Integer port;
#Autowired
private SimpMessagingTemplate simpMessagingTemplate;
private WebSocketStompClient webSocketStompClient;
#BeforeEach
public void initialize(){
webSocketStompClient = new WebSocketStompClient(new SockJsClient(List.of(new WebSocketTransport(new StandardWebSocketClient()))));
}
#Test #DisplayName("test subscription to /topic/plcs/connection-status")
void testSubscriptionToPlcConnectionEndpoint() throws Exception{
CountDownLatch latch = new CountDownLatch(1);
webSocketStompClient.setMessageConverter(new MappingJackson2MessageConverter());
StompSession stompSession = webSocketStompClient.connect("ws://localhost:" + port+"/api/ws", new StompSessionHandlerAdapter() {
}).get(1, TimeUnit.SECONDS);
stompSession.subscribe("/topic/plcs/connection-status", new StompFrameHandler() {
#Override
public Type getPayloadType(StompHeaders stompHeaders) {
return String.class;
}
#Override
public void handleFrame(StompHeaders stompHeaders, Object o) {
latch.countDown();
System.out.println("RECEIVED: "+o);
}
});
//stompSession.send("/topic/plcs/connection-status", "SENT FROM TEST!!!");
simpMessagingTemplate.convertAndSend("/topic/plcs/connection-status", "SENT FROM TEST!!!");
if (!latch.await(5, TimeUnit.SECONDS)){
fail("Message not received");
}
}
}
My configuration for WS looks like this:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/queue", "/topic");
config.setApplicationDestinationPrefixes("/app");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}
So, there are actually two problems ...
first is that you are using wrong messageConvertor (new MappingJackson2MessageConverter() instead of new StringMessageConverter())
the simpMessagingTemplate.convertAndSend("/topic/plcs/connection-status", "SENT FROM TEST!!!"); is fired before the client is subscribed, I have just tried to put there some delay before it with Thread.sleep(500); and it worked.
I'm trying to send message to subscribed user with spring-starter-websocket, but it looks like convertAndSend simply doesn't send message. #SendTo works.
My config:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
private final HttpHandshakeInterceptor httpHandshakeInterceptor;
public WebSocketConfig(HttpHandshakeInterceptor httpHandshakeInterceptor) {
this.httpHandshakeInterceptor = httpHandshakeInterceptor;
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").setAllowedOrigins("*").withSockJS().setInterceptors(httpHandshakeInterceptor);
}
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/notifications");
registry.setApplicationDestinationPrefixes("/app");
}
Controller:
#Controller
public class NotificationController {
private final NotificationService notificationService;
private final SimpMessagingTemplate template;
public NotificationController(NotificationService notificationService, SimpMessagingTemplate template) {
this.notificationService = notificationService;
this.template = template;
}
#MessageMapping("/echo")
public void send(String text) {
template.convertAndSend("/notifications", text);
}
}
Test Case:
#Autowired
NotificationService notificationService;
#Test
public void testSubscribe() throws ExecutionException, InterruptedException {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Authorization", "Bearer " + token);
StompSession stompSession = stompClient.connect(WEBSOCKET_URI, new WebSocketHttpHeaders(httpHeaders),
new StompSessionHandlerAdapter(){}).get();
stompSession.subscribe(WEBSOCKET_TOPIC, new DefaultStompFrameHandler());
stompSession.send("/app/echo", "Test".getBytes());
Assert.assertEquals("Test", blockingQueue.poll(1, SECONDS));
}
class DefaultStompFrameHandler implements StompFrameHandler {
#Override
public Type getPayloadType(StompHeaders stompHeaders) {
return byte[].class;
}
#Override
public void handleFrame(StompHeaders stompHeaders, Object o) {
blockingQueue.offer(new String((byte[]) o));
}
}
As result, i have emзty queue. #SentTo works perfect.
UPD: convertAndSend works, but only from controller.
P.S. Sorry for my English, hope you understood problem :-)
i have to develop a web socket server with spring that send to the client a message avery 5 sec. The client is written in react js. This is my server code:
#SpringBootApplication
#EnableAsync
#EnableScheduling
public class TestwsApplication {
public static void main(String[] args) {
SpringApplication.run(TestwsApplication.class, args);
}
}
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chatWS").setAllowedOrigins("*").withSockJS();
}
This is my scheduler that send to the channel /topic/message a message every 5 sec
#Component
public class ScheduledTasks {
#Autowired
WebSocketListener listener;
int i=0;
private static final Logger log = LoggerFactory.getLogger(ScheduledTasks.class);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
#Scheduled(fixedRate = 5000)
public void reportCurrentTime() {
if (i==0){
listener.pushSystemStatusToWebSocket("ok");
i=1;
}else{
listener.pushSystemStatusToWebSocket("errore");
i=0;
}
}
}
This is my service used by the scheduler to send the message to the clients
#Service
public class WebSocketListener {
#Autowired
private SimpMessagingTemplate webSocket;
#Async
public void pushSystemStatusToWebSocket (String newStatus){
System.out.println("inviooooooooooooooooooooooooooo");
webSocket.convertAndSend("/topic/messages", newStatus);
}
}
This is my react component
import SockJS from 'sockjs-client';
class Main extends React.Component {
constructor() {
super();
this.state = {
clickCount: 0,
};
}
componentDidMount(){
// this is an "echo" websocket service
console.log('didmount')
var sock = new SockJS('http://localhost:8080/chatWS');
sock.onopen = function() {
console.log('open socket ');
sock.send('test');
};
sock.onmessage = function(e) {
console.log('message');
console.log('message', e.data);
sock.close();
};
sock.onclose = function() {
console.log('close');
};
}
on the log i see only the post open socket ... i dont see any log inserted in onmessage... so the client did not receive the message. Why ? Can you help me ?
Thanks
Esoni
I want to send notification to specific user. My client side code is:
stompClient.connect({},function (frame) {
stompClient.subscribe('user/queue/notification', function(response){
alert(angular.fromJson(response.body));
});
Here's my server configuration:
#Configuration
#EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{
#Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/queue");
}
#Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/myWebSocketEndPoint")
.setAllowedOrigins("*")
.withSockJS();
}
}
Here's my server message-sender:
#Component
public class MenuItemNotificationSender {
public void sendNotification(MenuItemDto menuItem, String username) {
String address = "/queue/notification";
System.out.println(username);
messagingTemplate.convertAndSendToUser(username,address, menuItem);
}
}
The messages are sent correctly, to the correct username, but why client doesn't receive them?