Рекомендуется ли использовать отправленные события сервера для отправки уведомлений путем непрерывного запроса к базе данных? - PullRequest
2 голосов
/ 10 февраля 2020

Я хочу отправить sh уведомления в реальном времени (объект DTO для вошедшего в систему пользователя) на стороне клиента, постоянно запрашивая базу данных. Я использую Server Side Events для достижения того же. Тем не менее, я сталкиваюсь с несколькими проблемами в достижении этого. Я использую EventSource API в javascript.

  1. ОПРОС ВНУТРИ БЕСКОНЕЧНОГО L OOP

Поскольку мои данные находятся в базе данных, Мне постоянно нужно выполнять запросы для получения последних записей и использовать executor.execute(()->{ while(true) {emitter.send(data)} } Thread.sleep(5000)), пока пользователь не выйдет из системы. (a) Запросы к базе данных в бесконечном l oop и (b) Создание новых объектов ExecutorService вызывает исключение JDB C из пула и в конечном итоге приводит к зависанию приложения.

ИСПОЛЬЗОВАНИЕ SPRING BOOT @ Scheduled Это также не работает, так как мне нужно войти в систему user_id, который я не могу получить внутри аннотированного метода @Scheduled с использованием SpringContextHolder.getAuthentication, так как этот Cron не инициирован пользователем .

Я ошибаюсь, выбрав SSE вместо веб-сокетов, или есть ли способ реализовать Server Side для этого конкретного варианта использования?

Пожалуйста, помогите / направьте меня.

Ответы [ 2 ]

0 голосов
/ 12 февраля 2020

Удивительно, но да, это допустимый шаблон.

Опрос каждые 5 секунд может использовать меньше общих ресурсов, чем отправка базой данных уведомлений pu sh (даже при условии, что это поддерживает БД).

И по сравнению с тем, что клиент делает, скажем, AJAX вызов каждые 5 секунд, для чего требуется каждый раз устанавливать соединение с БД, это также может быть более эффективным (за счет того, что сокет SSE открыт все время).

Создание новых объектов ExecutorService вызывает исключение JDB C для пула и, в конечном итоге, приводит к зависанию приложения.

Является ли исчерпание пула из-за наличия только одного пользователь, опрашивая каждые 5 секунд? Или это связано с большим количеством пользователей, каждый из которых держит соединение с базой данных открытым?

Если последнее, сделайте пул достаточно большим, чтобы поддерживать максимальное количество одновременно подключенных пользователей, которое вы хотите разрешить.

Если первое, вы должны освободить ресурс после опроса, перед выполнением режима ожидания 5000 мс, или открыть ресурс один раз за пределами l oop, а затем найти способ просто повторно выполнить запрос внутри бесконечного l oop.

(Извините, я не знаком с ExecutorService или Spring; возможно, это просто слишком высокоуровневая абстракция для запросов к базе данных, и вам нужно использовать функции более низкого уровня?)

Кстати, SSE против веб-сокетов здесь не будет иметь значения. Веб-сокеты предоставляют вам более сложный протокол в обмен на то, что он является двусторонним, а не односторонним, но все остальное в значительной степени совпадает. Т.е. у вас все еще есть выделенный сокет между клиентом и вашим веб-сервисом, и у вас все еще есть бесконечный l oop, опрашивающий базу данных.

0 голосов
/ 10 февраля 2020

Если вы хотите отправить событие sh своему клиенту, вам лучше иметь концепцию события на бэкэнде, а не на опросе. Если вы хотите опросить свою базу данных, лучше пусть клиент сделает это. SSE или websocket не имеют значения в этом решении.

События CDI могут быть подходящим решением для ваших нужд.

  • Создайте класс событий EntityForLoggedInUsersChanged.
  • Внедрить в вашу службу Event<EntityForLoggedInUsersChanged>, чтобы изменить сущности, связанные с вошедшими в систему пользователями. запустить событие, когда они это делают.
  • Создайте службу, которая будет @Observe для этих событий, создайте dto, который вы хотите pu sh, получите канал для соответствующих пользователей и pu sh it.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...