Spring - 在事件发生时向WebSocket发送消息

3
我有以下情况:每次触发事件时,我需要在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个回答

6

创建一个您可以随时调用的方法的自定义通信服务类。我的做法是创建了一个名为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);
  }
}

谢谢,这正是我所寻找的。 - valent0ne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接