Spring - 在事件上向websocket发送消息

时间:2018-01-23 16:24:13

标签: java spring events websocket

我遇到以下情况:每次触发事件时,我都需要在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

1 个答案:

答案 0 :(得分:2)

使用您可以随时调用的方法创建自己的comm服务类。我所做的是使用静态方法创建一个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);
  }
}

然后,您可以通过CommService

初始化ContextRefreshHandler
@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);
  }
}