У меня есть следующий фрагмент кода:
@Controller
@EnableScheduling
public class QuoteController {
@Scheduled(fixedDelay=5000)
@SendTo(value = "/topic/quote")
public String sendPrice() {
return "message from scheduler";
}
}
И это не отправляет сообщение на канал. Но следующий код работает:
@Controller
@EnableScheduling
public class QuoteController {
@Autowired
public SimpMessageSendingOperations messagingTemplate;
@Scheduled(fixedDelay=5000)
public String sendPrice() {
messagingTemplate.convertAndSend("/topic/quote", "message from scheduler");
}
}
Я думаю, что @VikramSingh в некотором роде прав, хотя я не согласен с причиной: @SendTo работает, когда аннотируемый метод участвует во взаимодействиях обмена сообщениями - Spring вызывает его в ответ на полученное сообщение и принимает аннотацию @SendTo как указание на то, что должно быть создано ответное сообщение. Здесь sendPrice() вызывается Spring, но не в контексте обмена сообщениями, поэтому у Spring нет причин думать, что ожидается ответ - поэтому аннотация @SendTo игнорируется ...
Да, я думаю, когда метод аннотируется с помощью пружины @SendTo, рассматривает его как конечную точку обмена сообщениями, а когда он получает сообщение от клиента, он внутренне вызывает метод convertAndSend для отправки сообщения клиенту. Но в случае аннотации @Scheduled она будет вызвана позже, без получения сообщения от клиента. Поскольку клиент не задействован, нет смысла отправлять сообщение клиенту, которое может быть недоступно во время вызова.




Мы должны использовать аннотацию @SendTo только для функций, которые вызываются через websocket, это означает функции, аннотированные с помощью @MessageMapping.
Если вы хотите отправить сообщение в очередь другим способом, вам следует использовать messagingTemplate.convertAndSend.
Пример для @SendTo:
@MessageMapping("/hello") // from websocket
@SendTo("/topic/bla")
public String foo1(String message) {
return message;
}
Пример для .convertAndSend:
@Autowired
private SimpMessagingTemplate template;
@GetMapping("/{msg}") //from GET request
public void foo2(@PathVariable String msg) {
template.convertAndSend("/topic/bla", msg);
}
@SendToработает, когда запрос поступает из браузера и интерпретируется фреймворком Spring. ИconvertAndSend- это API, который можно использовать в любой среде. Поскольку вы используете его в Thread, это не конечная точка в spring, и значение, возвращаемое методомsendPrice(), не будет обработано spring.