RPC через STOMP с использованием Spring и корректной обработки ошибок на стороне сервера, распространяемых на клиентов

Мне нужно внедрить RPC поверх STOMP, где клиент работает с javascript в браузере, а серверная сторона реализована с использованием Spring возможностей обмена сообщениями.

При использовании @MessageMapping отлично подходит для нормального обмена сообщениями, я нахожу использование @SendToUser достаточно ограниченным для реализации RPC, потому что у клиента есть трудное время, чтобы понять, какой ответ связан с каким запросом в сценарии, когда выполняется несколько одновременных запросов из клиент.

Конечно, нет никаких проблем, когда делается только один запрос, и клиент ждет ответа, но проблемы возникают, когда клиент должен отслеживать несколько "открытых" вызовов rpc.

Мне удалось сделать систему в основном прекрасной, связав идентификатор с каждым запросом, то есть: клиент отправляет идентификатор вместе с сообщением, а сервер отвечает специальной оболочкой сообщения, содержащей этот идентификатор, поэтому клиент может связывать асинхронные ответы с запросами.

Это прекрасно работает, но имеет несколько ограничений:

  • Мне нужно разработать код, который должен понимать эту структуру, и это бросает вызов uitlity, чтобы иметь простые аннотированные методы.

  • когда код на стороне сервера генерирует исключение, вызываемый Spring @MessageExceptionHandler, и правильное исключение возвращается клиенту, но идентификатор запроса теряется, потому что обработчик не имеет (простого) способа доступа к нему.

Я знаю, что с rabbitmq мы можем добавить заголовок "ответ на" для каждого запроса, который должен быть связан со специальным ответом (ответ rpc), и это реализовано путем создания специальной временной очереди, автоматически выполняемой пользователем подписанный, но как я могу использовать эту схему в Spring? Кроме того, это свяжет меня с конкретным брокером.

Как я могу элегантно реализовать правильный вызов RPC в Spring, который правильно обрабатывает исключения на стороне сервера?

Я нахожу это общей проблемой, и я думаю, что Spring может значительно помочь реализовать его изначально.

Ответ 1

Это не совсем то, что вы требуете, но, возможно, вы можете попробовать что-то вроде этого: Переменные пути в Spring Отображение WebSockets @SendTo

Вы определяете ID на своем клиенте и отправляете id в очередь /user/queue/ {myid} На стороне обслуживающего вас будет класс, который выглядит следующим образом:

@MessageMapping("/user/queue/{myid}")
public void simple(@DestinationVariable String id, Object requestDto) {
    simpMessagingTemplate.convertAndSendToUser(userId, "/user/queue/" + id, responseDto);
}

Это решение может работать с тем же принципом, что и упоминаемое вами решение mk rabbit.

Надеюсь, что это поможет.