LINUX.ORG.RU

Реакция фронтенда на изменения данных на сервере при оповещении через websocket

 , , ,


0

1

Имеется бэкенд на springboot. Работа с БД осуществляется посредством spring-data-jpa. Еще есть фронтенд на vuejs.

Захотелось мне реализовать обновление страницы при изменении данных на сервере, для чего я завел websocket (sockjs, stomp). Вебсокет планирую пока использовать только для оповещения сервером всех заинтересованных об изменении данных.

Вопрос первый, об организации каналов оповещения. Допустим у меня есть четыре сущности: A, B, C, D. Еще есть три компонента:

  • cAB, его состояние зависит от сущностей A и B
  • cCD, его состояние зависит от сущностей C и D
  • cABC, его состояние зависит от сущностей A, B и C

Сущности могут изменяться на сервере в рамках одной транзакции в различных комбинациях. Хотелось бы минимизировать число обновлений компонентов при изменении данных на сервере.

Допустим вызов одного ресурса производит изменение сущностей A, B, C. В итоге я хотел бы чтобы в результате все три компонента обновились по одному разу.

Вариант первый: создать по каналу на сущность и при изменении каждой сущности постить в соответствующий ей канал сообщение. Каждый компонент подписывается на каналы сущностей, от которых зависит его состояние. Но тогда компонент cAB обновится два раза, первый раз по сообщению от канала A, второй раз по изменению по сообщению канала B. Решить эту проблему можно заведя таймер, который сбрасывался бы получив каждое сообщение. По таймауту происходило бы обновление. Таким образом следующие друг за другом сообщения приводили бы к одному единственному обновлению. Но тут надо во vuejs реализовывать эту логику на таймерах. И вообще нормальные ли это решение?

Вариант второй: сообщение об обновлении постилось бы в один единственный канал, сообщение содержало бы список сущностей, которые изменились. Минус один и существенный на мой взгляд: любой клиент получал бы сообщения об обновлении сущностей, которые ему даже не интересы в этот момент. А у меня есть сущности, которые обновляются раз в 5 секунд.

Какие есть более оптимальные варианты на ваш взгляд?

Вопрос второй. Так как клиенты не будут слать серверу никаких сообщений по вебсокету, аннотации @MessageMapping @SendTo для меня бесполезны, ибо отправка сообщений будет происходить из контроллеров rest посредством вызова SimpMessagingTemplate.this.template.convertAndSend Но транзакция закрывается при выходе из транзакционного метода. Получается даже если я вызываю convertAndSend в конце метода контроллера, данные еще не зафиксированы, а я уже шлю сообщение клиентам. Каким образом организовать отправку сообщения клиентам после успешной фиксации транзакции? Этот вопрос может быть связан со следующим.

Если подход с отправкой сообщения об изменении сущностей в канал соответствующий этой сущности является оптимальным, то я хотел автоматизировать отправку сообщений, чтобы в каждом методе контроллеров не приходилось вести учет сущностей, который я меняю. В голову пришла такая мысль: обрабатывать фиксацию транзакций, в каждом событии анализировать сущности, которые были повержены изменению, постить в каналы соответствующие этим сущностям сообщения. Это возможно технически? Отследить успешный коммит транзакции и перебрать измененные сущности в этой транзакции? И насколько кошерен этот подход?

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

Буду рад любым комментариям и советам.



Последнее исправление: popov-aa (всего исправлений: 2)

Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.