Найти - Пользователи
Полная версия: Подписка
Начало » Network » Подписка
1
PyCraft
Нужно реализовать обновление данных по подписке.
Клиент соединяется с TCP-сервером, выполняет запрос, получает данные.
На эти данные он подписывается, чтобы получать обновления в реальном времени.
Одновременно работающих пользователей может быть много.
Разные пользователи подписываются на разные данные.
Массивы данных большие, но меняются они незначительно(точечно).

Может быть есть стандартный паттерн решения такой задачи?
Как луше реализовать, какие подводные камни подстерегают?
Ferroman
Я вижу 2 способа:
1. Обновлять данные у пользователей по таймеру.
2. Обновлять каждый раз после изменения на сервере (то есть по событию)

По таймеру хорошо когда обновления проходят довольно часто, - пользователь может ставить частоту обновления.
При обновлении по событию система, в общем случае, такая:
1. Данные на сервере изменились
2. Вызывается обработчик, который получает список подписанных на такие изменения.
3. Клиентам посылается запрос на получение изменений
4. Отсылаются изменения - клиентская часть изменяет свои данные в соответствии с присланными изменениями.
Проблемы, собственно, те же, что и у баз данных - конфликты изменений и целостность данных. Дополнительно нужно отслеживать все ли изменения на клиентской стороне были обработаны правильно (тут решение довольно простое - подсчитывать контрольные суммы данных)
Так же есть возможна проблема, при слишком большом количестве полученных изменений одновременно, - но, думаю, этот вопрос можно решить/оптимизировать по надобности после performance-тестов.

Раньше делал кое-что подобное, но данных и клиентов было мало, возможно на больших обьёмах данных и большом количестве клиентов будут “свои” проблемы.
PyCraft
1 и 2 понятно
Ferroman
3. Клиентам посылается запрос на получение изменений
Как отослать клиенту запрос? Предполагается, что соединение активно(сокет открыт) и клиент ждет этого запроса recv() в отдельном потоке.
Если так, то может быть сразу попытаться отослать ему изменения, а затем прикладной логикой на сервере и на клиенте оптимизировать интенсивность передачи. Т.е. если данные совсем не отправляются в течение определенного времени, то закрыть соединение, а клиенту при следующем коннекте урезать квоту на подписку. При разрыве соединения на строне клиента также автоматически уменьшается квота(жадность запроса). Так, мне кажется, можно обойтись без пункта 3. Всё равно ресурс сервера уже использован и нет смысла задерживать готовый результат.
Эти обновления нужны для того, чтобы клиент видел самые актуальные данные.
Если с его стороны связь плохая, то это проблема клиента и ему нужно уменьшить запросы.
Может быть в ряде случаев, когда прием не очень критичен, вообще UDP отсылать?
Ferroman
Так, мне кажется, можно обойтись без пункта 3. Всё равно ресурс сервера уже использован и нет смысла задерживать готовый результат.
Да, конечно, можно и так. Тут выбор скорее зависит от конкретной задачи.
Может быть в ряде случаев, когда прием не очень критичен, вообще UDP отсылать?
Ну, я бы так не делал, - кроме случаев, когда система будет использоваться в локальной сети. Особенно если нужно что бы пользователь всегда имел максимально актуальные данные. Все-таки целостность данных обычно критичнее времени их доставки.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB