我正在尝试了解如何使用带Spring Boot的websocket将消息发布/广播到Javascript应用程序。我可以找到的所有示例都在使用StompJs客户端-但是我无法在客户端代码中使用StompJs,并且我不确定后端是否正确,这无济于事。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

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

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

}


只需使用一个简单的@Scheduled每5秒产生一次时间,然后将其发送到time主题(好吧,我相信这就是它的工作...)

@Component
@Slf4j
public class TimeSender {
    private static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern("HH:mm:ss");

    private SimpMessagingTemplate broker;

    @Autowired
    public TimeSender(final SimpMessagingTemplate broker) {
        this.broker = broker;
    }

    @Scheduled(fixedRate = 5000)
    public void run() {
        String time = LocalTime.now().format(TIME_FORMAT);

        log.info("Time broadcast: {}", time);

        broker.convertAndSend("/topic/time", "Current time is " + time);
    }
}


在尝试测试时,我有些困惑。使用Chrome的Simple websocket client插件,我必须在请求的末尾添加websocket才能进行连接。想要ws://localhost:8080/subscribe/websocket的连接如果没有websocket,我将无法连接,但是在任何示例或Spring文档中都找不到该连接?

第二个问题是如何订阅时间主题?所有StompJs客户端都调用类似client.subscribe("time")之类的东西。

我已经尝试过ws://localhost:8080/subscribe/topic/time/websocket,但是没有收到任何时间戳的机会。

我不确定我的后端代码是否错误,URL是否错误或是否缺少其他内容。

注意:我的@Controller从上面丢失了,因为我现阶段只专注于将消息从Spring发送到客户端,而不是接收消息,这是我理解的控制器只处理传入消息吗?

最佳答案

好吧,我想如果一个人过分迷恋,答案最终就会出现。找到您的帖子后,我几乎在http://www.marcelustrojahn.com/2016/08/spring-boot-websocket-example/处找到了所需的答案。有一个非常好的示例,它基本上可以完成您所描述的事情。区别在于他们使用Spring SimpMessagingTemplate将消息发送到队列。一旦我遵循了他的模式,所有这些都像魅力一样发挥了作用。这是相关的代码片段:

@Autowired
SimpMessagingTemplate template

@Scheduled(fixedDelay = 20000L)
@SendTo("/topic/pingpong")
public void sendPong() {
   template.convertAndSend("/topic/pingpong", "pong (periodic)")
}


该方法是void,因此convertAndSend()方法可以处理主题发布,而不是我在网络上看到的几乎所有其他教程所涉及的return语句。这有助于解决我的问题。

07-28 02:34
查看更多