本教程介绍如何使用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>
|