bat*_*anz 8 java spring spring-mvc websocket spring-websocket
我正在使用Spring框架,我有一个工作的websocket控制器,如下所示:
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws InterruptedException {
return new Greeting("Hello, " + message.getName() + "!");
}
}
Run Code Online (Sandbox Code Playgroud)
我也有这个配置:
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
那部分效果很好!我可以使用Stomp.js在两个或多个浏览器之间成功发送和接收消息.这是不起作用的部分.我已经实现了一个ServletContextListener包含一个自定义对象,为简单起见,我称之为"通知器".通知程序侦听在服务器端发生的某些事件.然后它调用'notify'方法,该方法应该将有关事件的详细信息发送给所有客户端.但它不起作用.
@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 + "!"));
}
}
Run Code Online (Sandbox Code Playgroud)
我没有例外.在SimpMessagingTemplate已经成功地由Spring注入,所以它不是空.我已经能够步入春天代码,并已经想通了,对SimpleBrokerMessageHandler的subscriptionRegistry用时是空的SimpMessagingTemplate.因此它必须是与控制器使用的实例不同的实例.如何获得subscriptionRegistry控制器使用的相同内容?
解决方案是使用 Spring 的ApplicationListener类而不是ServletContextListener,并专门监听ContextRefreshedEvent.
这是我的工作示例:
@Component
public class MessagingApplicationListener implements ApplicationListener<ContextRefreshedEvent>, Notifiable {
private final NotifierFactor notifierFactory;
private final MessageSendingOperations<String> messagingTemplate;
private Notifier notifier;
@Autowired
public MessagingApplicationListener(NotifierFactor notifierFactory, MessageSendingOperations<String> messagingTemplate) {
this.notifierFactory = notifierFactory;
this.messagingTemplate = messagingTemplate;
}
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if (notifier == null) {
notifier = notifierFactory.create(this);
notifier.start();
}
}
public void notify(NotifyEvent event) {
messagingTemplate.convertAndSend("/topic/greetings", new Greeting("Hello, " + event.subject + "!"));
}
@PreDestroy
private void stopNotifier() {
if (notifier != null) {
notifier.stop();
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12569 次 |
| 最近记录: |