使用Spring Boot调度WebSocket推送的教程和源码 - Baeldung


本教程介绍如何使用WebSockets将计划的消息从服务器发送到浏览器。使用Spring的实用程序类SimpMessagingTemplate使通过WebSocket推送服务器消息会更容易。
示例的源代码可 在GitHub上获得
 
为了推送消息,我们使用实用程序类SimpMessagingTemplate。默认情况下,它在Spring Context中以@Bean形式提供。当AbstractMessageBrokerConfiguration 在类路径中时,可用通过自动配置声明它。这样就可以将其注入任何Spring组件中。

假设这个实用类注入了一个名为simpMessagingTemplate的变量中,使用它来将消息发布到主题/ topic/pushmessages:

simpMessagingTemplate.convertAndSend("/topic/pushmessages"
  new OutputMessage(
"Chuck Norris", faker.chuckNorris().fact(), time));

使用SimpMessagingTemplate通过WebSocket发送OutputMessage 这个POJO消息, 下面是定义何时发送消息,@Scheduled注释允许的方法重复执行。有了它,我们可以使用基于速率的简单调度或更复杂的“ cron”表达式。

@Service
public class ScheduledPushMessages {

    @Scheduled(fixedRate = 5000)
    public void sendMessage(SimpMessagingTemplate simpMessagingTemplate, ChuckNorris chuckNorris) {
        String time = new SimpleDateFormat("HH:mm").format(new Date());
        simpMessagingTemplate.convertAndSend(
"/topic/pushmessages"
          new OutputMessage(
"Chuck Norris (@Scheduled)", chuckNorris().fact(), time));
    }
    
}

我们用@Scheduled(fixedRate = 5000)注释sendMessage方法。这使sendMessage每五秒钟运行一次。然后,我们使用simpMessagingTemplate实例将OutputMessage发送到主题。
simpMessagingTemplate 和chuckNorris实例是从Spring上下文作为方法参数注入。
如果使用WebFlux,则可以使用Flux::interval运算符。
以上是核心部分。
 
下面是外围大概代码,下面建立一个服务器端的API端点:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

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

客户端是一个简单的HTML页面。它使用SockJS客户端和STOMP消息协议。

让我们看看客户端如何订阅主题:

<html>
<head>
    <script src="./js/sockjs-0.3.4.js"></script>
    <script src=
"./js/stomp.js"></script>
    <script type=
"text/javascript">
       
// ...
        stompClient = Stomp.over(socket);
    
        stompClient.connect({}, function(frame) {
           
// ...
            stompClient.subscribe('/topic/pushmessages', function(messageOutput) {
                showMessageOutput(JSON.parse(messageOutput.body));
            });
        });
       
// ...
    </script>
</head>
<!-- ... -->
</html>