简体   繁体   中英

Java Spring boot websocket communication with JS

I have the following WebSocketConfig in my Spring boot app:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app");
        registry.enableSimpleBroker("/topic");
    }
}

and this code in my controller:

@Autowired
    private SimpMessagingTemplate template;

    @Scheduled(fixedRate = 5000)
    public void getMessage() {
        System.out.println("scheduled");
        this.template.convertAndSend("/topic/updateService", "Hello");
    }

I'm trying to read those messages using my javascript application this way:

let socket = new SockJS(`https://localhost:8443/ws`);
    let stompClient = Stomp.over(socket);

    stompClient.connect({}, () => {
      stompClient.subscribe('/topic/updateService', (data) => {
        console.log("New message!");
        console.log(data);
      });
    }, () => {
      console.log('failed');
    });

Although I'm subscribed to /updateService, I can't get any message.

Console log shows all fine:

在此处输入图片说明

Although in my Spring boot app I see scheduled in my console, I get no message in my client.

Any ideas what could have gone wrong?

Sorry I don't have enough reputation to leave a comment to your post, so I will reply.

  1. you can enable logging in application.properties to see what actually happens with WS connection.

     logging.level.org.springframework.messaging=trace logging.level.org.springframework.web.socket=trace
  2. connected to server undefined doesn't mean that something is wrong. This line appears every time.

  3. I've tried to reproduce your issue and it works fine on my side. Do you have additional routing or security configuration (I've noticed http s and a custom port)? Here is the code in case you need to check:

Controller:

@Controller
public class SomeController {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @Scheduled(fixedDelay = 1000)
    private void send() {
        simpMessagingTemplate.convertAndSend("/topic/updateService", "Hello");
    }
}

Main app & Websocket config (don't forget @EnableWebSocketMessageBroker ):

@SpringBootApplication
@EnableScheduling
@EnableWebSocketMessageBroker
public class Main extends AbstractWebSocketMessageBrokerConfigurer {
    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.setApplicationDestinationPrefixes("/app");
        registry.enableSimpleBroker("/topic");
    }
}

And this is JS code:

<script type="text/javascript">
        var stompClient = null;

        function connect() {
            var socket = new SockJS("http://localhost:8443/ws");
            stompClient = Stomp.over(socket);
            stompClient.connect({}, function () {
                stompClient.subscribe('/topic/updateService', function (data) {
                    console.log(data);
                });
            });
        }

        function disconnect() {
            if (stompClient != null) {
                stompClient.disconnect();
            }
            console.log("Disconnected");
        }

</script>

I know the question is old, but perhaps my answer will help someone else.

I had a similar issue. My task was to keep user updated regarding some ongoing process, so my application had to send every 5 seconds a message.

The front-end Vue.js application is served separately on node. Inside component which had to monitor the task I have added:

<script>    
import SockJS from 'sockjs-client'
const Stomp = require('stompjs')
const socket = new SockJS('http://localhost:8088/monitor/activity',{transports: ['websocket'] })

// Usual Vue-js stuff
methods: {
  subscribe (frame) {
    console.log('Subscribed to: ' + frame)
    this.stompClient.subscribe('/web-socket/activity', (payload) => {
      console.log('Successfully handled message :' + payload)
    })
  },
  connect () {
    this.stompClient = Stomp.over(socket)
    this.stompClient.connect({}, this.subscribe)
  }
},
mounted() {
  this.connect
}
</script>

On server side (Spring Application written in Kotlin) I have added Configuration class

@Configuration
class WebSocketConfig : WebSocketMessageBrokerConfigurer {

    override fun registerStompEndpoints(registry: StompEndpointRegistry) {

        registry.addEndpoint("/monitor/activity")
                .setAllowedOrigins("*")
                .withSockJS()
    }
}

As you may I see, I DO NOT override configureMessageBroker method

In main class I enable web-sockets and scheduling

@SpringBootApplication
@EnableScheduling
@EnableWebSocketMessageBroker
@EnableWebSocket
public class SpringBootVuejsApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootVuejsApplication.class, args);
    }
}

And here is component that sends messages to socket :

@Component
class LoanScheduledCron
@Autowired constructor(
        private val messagingTemplate: SimpMessagingTemplate
) {

    @Scheduled(fixedDelay = 5000)
    fun getSchedulersActivity () {
        messagingTemplate.convertAndSend("/web-socket/activity", "Still active")
    }
}

Please note, that I have to write full destination as a parameter when calling method convertAndSend .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM