2012-03-06 28 views
3

我正在製作一款使用redis來存儲遊戲狀態的遊戲。它能夠很好地跟蹤地點和玩家,但我沒有一個好方法來清理閒置的玩家。如何清理redis中未激活的玩家?

每次玩家移動(這是一個半緩慢移動的遊戲,認爲每秒1-5幀),我會更新新位置的哈希值並刪除舊的位置密鑰。

追蹤活躍球員的最佳方式是什麼?我想到以下內容

  1. 設置用戶過期的某個鍵。更新每個心跳或移動。問題是地點存儲在散列表中,所以如果用戶密鑰過期,玩家仍然會在同一個地點。
  2. 相同,但使用的pub/sub監聽到期並完成清理(似乎過於複雜)的有序集合
  3. 商店心跳,有一個過程運行每X秒尋找老玩家。每次心跳更新分數。
  4. 徹底改變我存儲位置的方式,以便我可以使用過期..不知何故?

還有其他想法嗎?

回答

4

也許使用單獨 redis的數據結構(雖然相同的數據庫)來跟蹤用戶活動 和用戶位置。

例如,當前的在線分別使用redis的軌道的用戶設置

[我的代碼段是在python使用redis的-python綁定,並且在瓶適於從example app(蟒微框架) ;示例應用程序和框架都是由阿明Ronacher。]

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) 

因此,要獲得所有活躍用戶只需工會所有帶電鍵(在這個例子裏,是10個 鍵,一個純粹的任意數字),像這樣:

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

由於TTL,這解決了您的「清理」問題 - 非活動用戶不會出現在您的活動密鑰中,因爲他們經常回收 - 即在活動用戶中僅鎖定舊時間戳,而這些時間戳不會在此示例中持續存在(但也許是由redis寫入永久存儲區到期前)。無論如何,這會從活動的redis數據庫中清除非活動用戶。

+0

謝謝!要清楚:我必須清理我的位置信息爲非活動用戶。我真的需要知道非法行爲,所以我可以從位置哈希中刪除它們的位置。 – 2012-03-06 14:17:11

+0

@SeanClarkHess:當然;我想到的是,一旦你獲得了活躍的用戶(例如,來自「active_users」函數),然後檢查你的位置哈希中是否存在這些鍵。邏輯是「如果不是[hash]中的鍵值,那麼在該用戶的位置散列處調用」hset「傳遞任何你希望位置值爲非活動播放器的位置值。 – doug 2012-03-07 09:02:04