Java Spring引导websocket与JS的通信

时间:2017-10-10 08:56:20

标签: java spring spring-boot websocket stomp

我的Spring启动应用程序中有以下WebSocketConfig:

@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");
    }
}

和我控制器中的代码:

@Autowired
    private SimpMessagingTemplate template;

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

我正在尝试使用我的javascript应用程序以这种方式阅读这些消息:

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');
    });

虽然我订阅了/ updateService,但我无法收到任何消息。

控制台日志显示一切正常:

answer

虽然在我的Spring启动应用程序中,我在控制台中看到scheduled,但我的客户端没有收到任何消息。

任何可能出错的想法?​​

2 个答案:

答案 0 :(得分:0)

抱歉,我没有足够的声誉对你的帖子发表评论,所以我会回复。

  1. 您可以在application.properties中启用日志记录,以查看WS连接实际发生的情况。

    logging.level.org.springframework.messaging=trace
    logging.level.org.springframework.web.socket=trace
    
  2. connected to server undefined并不代表出现问题。每行都会显示此行。

  3. 我试图重现你的问题,它在我身边很好用。您是否有其他路由或安全配置(我注意到http s 和自定义端口)?以下是您需要检查的代码:

  4. 控制器:

    @Controller
    public class SomeController {
    
        @Autowired
        private SimpMessagingTemplate simpMessagingTemplate;
    
        @Scheduled(fixedDelay = 1000)
        private void send() {
            simpMessagingTemplate.convertAndSend("/topic/updateService", "Hello");
        }
    }
    

    主要应用程序& Websocket配置(不要忘记@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");
        }
    }
    

    这是JS代码:

    <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>
    

答案 1 :(得分:0)

我知道这个问题很旧,但是也许我的回答会对别人有所帮助。

我有一个类似的问题。我的任务是让用户了解一些正在进行的过程,因此我的应用程序必须每5秒发送一条消息。

前端Vue.js应用程序在节点上单独提供。内部组件必须监视我添加的任务:

<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>

在服务器端(用Kotlin编写的Spring应用程序),我添加了Configuration类

@Configuration
class WebSocketConfig : WebSocketMessageBrokerConfigurer {

    override fun registerStompEndpoints(registry: StompEndpointRegistry) {

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

您可能会看到,我请勿覆盖configureMessageBroker方法

在主类中,我启用网络套接字和计划

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

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

这是将消息发送到套接字的组件:

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

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

请注意,调用方法convertAndSend时,我必须写完整的目标位置作为参数。