Как убрать неактивных игроков в redis? - PullRequest
3 голосов
/ 06 марта 2012

Я делаю игру, в которой используется redis для сохранения состояния игры.Он хорошо отслеживает локации и игроков, но у меня нет хорошего способа убрать неактивных игроков.

Каждый раз, когда игрок движется (это полумедкая игра. Думайте 1-5 кадров в секунду), я обновляю хеш с новым местоположением и удаляю старый ключ местоположения.

Каков наилучший способ отслеживать активных игроков?Я подумал о следующем

  1. Установить некоторые ключи на пользователя, чтобы истечь.Обновляйте каждое сердцебиение или движение.Проблема в том, что местоположения хранятся в хэше, поэтому, если срок действия ключа пользователя истечет, игрок все равно будет в том же месте.
  2. То же самое, но используйте pub / sub, чтобы прослушать истечение срока и завершить очистку (кажется слишком сложным)
  3. Хранить биения в отсортированном наборе, запускать процесс каждые X секунды для поискастарые игроки.Обновлять счет за каждое сердцебиение.
  4. Полностью обновите способ хранения мест, чтобы я мог использовать срок действия ... каким-то образом?

Есть еще идеи?

1 Ответ

4 голосов
/ 06 марта 2012

Возможно использовать отдельные структуры данных redis (хотя и в той же базе данных) для отслеживания активности пользователей и местоположение пользователя.

Например, отслеживать пользователей, которые в настоящее время онлайн отдельно, используя redis sets :

[мой фрагмент кода в python использует привязки redis-python и адаптирован из примера приложения в Flask (микро-фреймворк python); Пример приложения и фреймворк от Армина Ронахера.]

from redis import Redis as redis
from time import time

r1 = redis(db=1)

при вызове указанной ниже функции создается ключ на основе текущего времени Unix в минутах. а затем добавляет пользователя в набор, имеющий этот ключ. Я полагаю, вы бы хотели установите срок действия, скажем, 10 минут, так что в любой момент времени у вас есть 10 живых ключей (по одному в минуту).

def record_online(player_id):
    current_time = int(time.time())
    expires = now + 600     # 10 minutes TTL
    k1 = "playersOnline:{0}".format(now//60)
    r1.sadd(k1, player_id)
    r1.expire(k1, expires)

Таким образом, чтобы получить всех активных пользователей, просто union всех живых ключей (в данном примере это 10 ключи, чисто произвольное число), вот так:

def active_users(listOfKeys):
    return r1.sunion(listOfKeys)

Это решает ваши проблемы с «очисткой» из-за TTL - неактивные пользователи не будут появляться в ваших живых ключах, потому что они постоянно перезаписываются - то есть, у активных пользователей используются только старые метки времени, которые не сохраняются в этом примере (но, возможно, записываются в постоянное хранилище с помощью redis до истечения срока действия). В любом случае, это удаляет неактивных пользователей из вашей активной базы данных redis.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...