ConvertAndSend vs. SendTo примечание

У меня есть следующий фрагмент кода:

@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");
    }
}
@SendTo работает, когда запрос поступает из браузера и интерпретируется фреймворком Spring. И convertAndSend - это API, который можно использовать в любой среде. Поскольку вы используете его в Thread, это не конечная точка в spring, и значение, возвращаемое методом sendPrice(), не будет обработано spring.
Vikram Singh 09.11.2018 05:55

Я думаю, что @VikramSingh в некотором роде прав, хотя я не согласен с причиной: @SendTo работает, когда аннотируемый метод участвует во взаимодействиях обмена сообщениями - Spring вызывает его в ответ на полученное сообщение и принимает аннотацию @SendTo как указание на то, что должно быть создано ответное сообщение. Здесь sendPrice() вызывается Spring, но не в контексте обмена сообщениями, поэтому у Spring нет причин думать, что ожидается ответ - поэтому аннотация @SendTo игнорируется ...

moilejter 09.11.2018 06:02

Да, я думаю, когда метод аннотируется с помощью пружины @SendTo, рассматривает его как конечную точку обмена сообщениями, а когда он получает сообщение от клиента, он внутренне вызывает метод convertAndSend для отправки сообщения клиенту. Но в случае аннотации @Scheduled она будет вызвана позже, без получения сообщения от клиента. Поскольку клиент не задействован, нет смысла отправлять сообщение клиенту, которое может быть недоступно во время вызова.

Vikram Singh 09.11.2018 06:10
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
3
707
1

Ответы 1

Мы должны использовать аннотацию @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);
}

Другие вопросы по теме