【发布时间】:2014-10-23 01:54:47
【问题描述】:
我正在使用 Spring 框架,并且我有一个可以工作的 websocket 控制器,如下所示:
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws InterruptedException {
return new Greeting("Hello, " + message.getName() + "!");
}
}
我也有这个配置:
@Configuration
@EnableWebSocketMessageBroker
public class HelloWebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/hello").withSockJS();
}
}
那部分效果很好!我可以使用 Stomp.js 在两个或多个浏览器之间成功发送和接收消息。这是不起作用的部分。我已经实现了一个ServletContextListener,其中包含一个自定义对象,为简单起见,我称之为“通知程序”。通知程序侦听服务器端发生的某些事件。然后它调用“通知”方法,该方法应该将有关事件的详细信息发送给所有客户端。但是,它不起作用。
@WebListener
public class MessageListener implements ServletContextListener, Notifiable {
private Notifier notifier;
@Autowired
private SimpMessagingTemplate messageSender;
public MessageListener() {
notifier = new Notifier(this);
}
public void contextInitialized(ServletContextEvent contextEvent) {
WebApplicationContextUtils
.getRequiredWebApplicationContext(contextEvent.getServletContext())
.getAutowireCapableBeanFactory()
.autowireBean(this);
notifier.start();
}
public void contextDestroyed(ServletContextEvent contextEvent) {
notifier.stop();
}
public void notify(NotifyEvent event) {
messageSender.convertAndSend("/topic/greetings", new Greeting("Hello, " + event.subject + "!"));
}
}
我没有遇到异常。 SimpMessagingTemplate 已经被 Spring 成功注入,所以它不为空。我已经能够进入 Spring 代码并发现使用 SimpMessagingTemplate 时 SimpleBrokerMessageHandler 的 subscriptionRegistry 是空的。因此,它必须是与控制器正在使用的实例不同的实例。如何获得控制器使用的相同subscriptionRegistry?
【问题讨论】:
-
好奇你是否找到了答案。从 Spring ApplicationEvent 类调用时会发生相同的行为。
-
很抱歉这么久才回到这个问题。我已经在下面发布了我的解决方案。
标签: java spring spring-mvc websocket spring-websocket