【问题标题】:Spring - send message to websocket on eventSpring - 在事件中向 websocket 发送消息
【发布时间】:2018-07-02 13:16:19
【问题描述】:

我有以下情况:每次触发事件时,我都需要在 websocket 上发送消息。

MessageController.java

@Controller
public class MessageController {

    @Autowired
    private SimpMessagingTemplate template;

    @RequestMapping(path="/messages", method=POST)
    public void send(String message) {
        this.template.convertAndSend("/topic/messages", message);
    }
}

KafkaConsumeEventHandler.java

@Component
public class KafkaConsumeEventHandler implements ApplicationListener<KafkaConsumeEvent> {

    private static final Logger LOGGER = LoggerFactory.getLogger(KafkaConsumeEventHandler.class);

    public void onApplicationEvent(final KafkaConsumeEvent event) {
        LOGGER.info("event detected: publishing...");
        LOGGER.info("message to be published: {}",event.getMessage());
        //INVOKE CONTROLLER TO SEND MESSAGE HERE
        LOGGER.info("event published to websocket.");

    }

}

是否可以在事件处理程序内部调用控制器的send() 方法?有没有更好的方法?

编辑 如果我在事件处理程序中执行this.template.convertAndSend("/topic/messages", message);(自动装配 SimMessagingTemplate),我会得到一个 nullPointerException

【问题讨论】:

    标签: java spring events websocket


    【解决方案1】:

    使用可以随时调用的方法创建自己的通信服务类。我所做的是创建一个带有静态方法发送的CommService

    public class CommService {
    
      private static SimpMessagingTemplate template;
    
      public static void setTemplate(SimpMessagingTemplate tmplt) {
        template = tmplt;
      }
    
      public static void send(String message) {
        template.convertAndSend("/topic/messages", message);
      }
    }
    

    然后你可以通过ContextRefreshHandler初始化CommService

    @Component
    public class ContextRefreshedHandler implements ApplicationListener<ContextRefreshedEvent> {
    
      private static Logger logger = LoggerFactory.getLogger(ContextRefreshedHandler.class);
    
      @Autowired
      private SimpMessagingTemplate template;
    
      @Override
      public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
          //Initialize the template for web socket messages
          CommService.setTemplate(template);
        } catch (Exception ex) {
          logger.error(getClass().getName(), ex);
        }
      }
    }
    

    这将在服务器启动时初始化您的模板,然后在您需要发送消息的整个应用程序中初始化您只需使用CommService.send("message");

    因此您可以将您的 MessageController 更改为此

    @Controller
    public class MessageController {
    
      @Autowired
      private SimpMessagingTemplate template;
    
      @RequestMapping(path="/messages", method=POST)
      public void send(String message) {
        CommService.send(message);
      }
    }
    

    【讨论】:

    • 谢谢,这正是我想要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 2016-04-28
    • 2016-12-19
    • 2014-08-28
    • 2016-02-16
    • 2020-05-06
    • 1970-01-01
    相关资源
    最近更新 更多