2014-08-29 16 views
5

我使用Spring框架和我有一個工作的WebSocket控制器,它看起來像這樣:通過SimpMessagingTemplate中的ServletContextListener發送短消息到所有客戶端

@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,其中包含一個自定義對象,爲簡單起見,我稱之爲「通知程序」。通知程序偵聽某些事件發生在服務器端。然後它調用'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 + "!")); 
    } 
} 

我沒有得到異常。 SimpMessagingTemplate已被Spring成功注入,所以它不爲空。我已經能夠進入Spring代碼,並發現在使用SimpMessagingTemplate時,SimpleBrokerMessageHandlersubscriptionRegistry爲空。所以它必須是一個獨立於控制器正在使用的實例。我怎樣才能得到控制器使用的相同的subscriptionRegistry

+0

好奇,如果你找到了答案。從Spring ApplicationEvent類調用時會發生相同的行爲。 – 2014-09-28 23:12:28

+0

很抱歉,經過這麼多時間後才能回到這裏。我已在下面發佈我的解決方案。 – battmanz 2015-03-04 18:39:15

回答

1

解決方案是使用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(); 
     } 
    } 
} 
+0

什麼是Notifiable,NotifierFactor和Notifier?請幫助,我只想打電話給我的websocket。 – 2016-08-11 14:10:31

+0

這些是我在現場發明的抽象概念,以說明我的觀點。但是,它們代表您在應用程序中可能具有的真實世界的服務。如果你使用的是WebSocket,那麼我假設你有一些服務器端事件發生,你想把消息推送給客戶端。這些抽象概念僅代表服務器端事件。 – battmanz 2016-08-11 20:22:18

+0

我在與控制器相同的類中有SimpMessagingTemplate,並且我打電話給webserice使用模板來調用websocket,但沒有錯誤,但我的websocket未被調用。 – 2016-08-12 07:38:58

相關問題