Java 如何使用Spring向websocket发送消息?

Java 如何使用Spring向websocket发送消息?,java,spring-boot,websocket,spring-websocket,stomp,Java,Spring Boot,Websocket,Spring Websocket,Stomp,我在我的Springboot web应用程序中使用websocket端点控制器从前端以Javascript发送和接收消息,但我不想从前端发送和接收消息,而是希望从后端(即Java)发送消息,在前端接收消息,即JS/HTML 到目前为止,我发现我可以使用并注入classSimpMessagingTemplate.convertAndSend,但我在前端websocket上没有收到任何东西。我已经从前端测试了它,它将正常发送/接收,但不是从java发送,而是从JS接收 我在这里被难住了,已经检查了这

我在我的Springboot web应用程序中使用websocket端点控制器从前端以Javascript发送和接收消息,但我不想从前端发送和接收消息,而是希望从后端(即Java)发送消息,在前端接收消息,即JS/HTML

到目前为止,我发现我可以使用并注入class
SimpMessagingTemplate.convertAndSend
,但我在前端websocket上没有收到任何东西。我已经从前端测试了它,它将正常发送/接收,但不是从java发送,而是从JS接收

我在这里被难住了,已经检查了这些讨论:

我的websocket控制器

@控制器
公共类GPIOControllerWS{
@消息映射(“/gpio”)
@发送到(“/topic/gpio”)
公共静态GPIOMessage sendGPIOMessage(GPIOMessage消息){
返回消息;
}
@消息映射(“/test”)
@发送到(“/topic/testpage”)
公共静态测试sendTestMessage(测试消息){
返回消息;
}
}
我的websocket配置

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        /* endpoints that the STOMP client subscribes to in JS */
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/test");
        registry.addEndpoint("/test").withSockJS();
    }
}
遵循来自的解决方案

@组件
公共类MessagingApplicationListener实现ApplicationListener{
私有静态最终记录器log=LoggerFactory.getLogger(MessagingApplicationListener.class);
私有最终消息发送操作消息模板;
@自动连线
公用MessagingApplicationListener(MessageSendingOperations messagingTemplate){
this.messagingTemplate=messagingTemplate;
}
@凌驾
ApplicationEvent(ContextRefreshedEvent事件)上的公共无效{
log.info(event.toString());
系统输出打印项次(事件);
messagingTemplate.convertAndSend(“/topic/gpio”,新的GPIOMessage(“3”,1));
}
公共无效通知(字符串通知){
日志信息(“已发送通知”);
messagingTemplate.convertAndSend(“/topic/gpio”,新的GPIOMessage(“3”,1));
}
}
我从另一个
@组件
类调用
messagingApplicationListener.notify
。 当我在那一行上放置断点并尝试调试时,调试器甚至没有到达那一行。尽管Application Event上的日志消息已被记录。所以如果我在这个方法中调试,我会得到这个

目标前缀
/user
,是否正确?它与我的websocket控制器端点不匹配,这是问题所在吗

编辑: 我在
simpMessageTemplate.sendAndConvert(“/topic/gpio”,object)
调用中跟踪了调试器,我认为在
SimpleBrokerMessengerHandler.java

protected void sendMessageToSubscribers(@Nullable String destination, Message<?> message) {
        MultiValueMap<String,String> subscriptions = this.subscriptionRegistry.findSubscriptions(message);
        if (!subscriptions.isEmpty() && logger.isDebugEnabled()) {
            logger.debug("Broadcasting to " + subscriptions.size() + " sessions.");
        }
        long now = System.currentTimeMillis();
        subscriptions.forEach((sessionId, subscriptionIds) -> {
            for (String subscriptionId : subscriptionIds) {
                SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
                initHeaders(headerAccessor);
                headerAccessor.setSessionId(sessionId);
                headerAccessor.setSubscriptionId(subscriptionId);
                headerAccessor.copyHeadersIfAbsent(message.getHeaders());
                headerAccessor.setLeaveMutable(true);
                Object payload = message.getPayload();
                Message<?> reply = MessageBuilder.createMessage(payload, headerAccessor.getMessageHeaders());
                SessionInfo info = this.sessions.get(sessionId);
                if (info != null) {
                    try {
                        info.getClientOutboundChannel().send(reply);
                    }
                    catch (Throwable ex) {
                        if (logger.isErrorEnabled()) {
                            logger.error("Failed to send " + message, ex);
                        }
                    }
                    finally {
                        info.setLastWriteTime(now);
                    }
                }
            }
        });
    }
受保护的void sendMessageToSubscribers(@Nullable String destination,Message Message){
多值映射订阅=this.subscriptionRegistry.findSubscriptions(消息);
如果(!subscriptions.isEmpty()&&logger.isDebugEnabled()){
debug(“广播到“+订阅.size()+”会话”);
}
long now=System.currentTimeMillis();
subscriptions.forEach((sessionId,subscriptionId)->{
for(字符串subscriptionId:subscriptionId){
SimpMessageHeaderAccessor headerAccessor=SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE);
初始化标头(标头Accessor);
headerAccessor.setSessionId(会话ID);
headerAccessor.setSubscriptionId(subscriptionId);
headerAccessor.copyHeadersFabSent(message.getHeaders());
headerAccessor.setLeaveMutable(真);
对象负载=message.getPayload();
Message reply=MessageBuilder.createMessage(有效负载,headerAccessor.getMessageHeaders());
SessionInfo=this.sessions.get(sessionId);
如果(信息!=null){
试一试{
info.getClientOutboundChannel().send(reply);
}
捕获(可丢弃的ex){
if(logger.isErrorEnabled()){
logger.错误(“未能发送”+消息,例如);
}
}
最后{
info.setLastWriteTime(现在);
}
}
}
});
}
变量
subscriptions.size()=0
。那么,是不是我没有正确设置Javascript端的订阅?我不这么认为,因为JS的发送/接收正在使用这些websocket端点。我认为我使用了错误的消息代理