Java 如何使用Spring向websocket发送消息?
我在我的Springboot web应用程序中使用websocket端点控制器从前端以Javascript发送和接收消息,但我不想从前端发送和接收消息,而是希望从后端(即Java)发送消息,在前端接收消息,即JS/HTML 到目前为止,我发现我可以使用并注入classJava 如何使用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接收 我在这里被难住了,已经检查了这
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端点。我认为我使用了错误的消息代理