django 频道在组用户之间共享实例变量
Posted
技术标签:
【中文标题】django 频道在组用户之间共享实例变量【英文标题】:django channels share instance variable between group users 【发布时间】:2020-05-20 15:34:03 【问题描述】:我正在 django 上开发一个在线游戏,我正在使用频道进行实时连接,但不幸的是,对于每个用户,我都有一个单独的游戏实例。
我想要的是,对于第一个用户,我使用 StartGame
的对象开始游戏,并希望对其他用户也使用相同的实例对象,因为我想分享游戏的当前状态。
我怎样才能只与该组的其他成员共享游戏实例?
我的一个想法是将游戏的当前状态保存在一个文件中,并将文件的路径保存在 db 中,让另一个用户检索保存的游戏状态并玩他/她的机会并再次保存,但这是否有效以及正确的做法?
网络游戏的实际场景是什么?
更新
我已经实现了,但它是正确的方式还是安全的?
我创建了一个全局变量GAME_POOL =
并为第一个用户存储了带有键channel_group_name
的游戏实例,然后为其他用户检查GAME_POOL
是否具有channel_group_name
的现有值,然后设置self.game = GAME_POOL['channel_group_name']
及其工作。
但这又是实现这一目标的安全且好方法?
游戏结束后我将删除它。
【问题讨论】:
将游戏状态直接存储在数据库中怎么样?为什么要先存储在文件中? 这对我来说很难,因为游戏有太多的模型,每一步都保存在数据库上,而且对于很多用户来说,数据库上的负载是无用的......我看到的最佳选择是共享实例群用户之间的游戏……如果能实现那就更好了。 @Ken4scholars 请检查更新 如果你想将状态存储在内存而不是数据库上,如果组数太大而导致内存膨胀怎么办?您是否需要持久性,因为游戏工作者可能会遇到问题并关闭?所有这些都取决于您的用例,这是您必须自己回答的问题。没有唯一正确的方法。 @Ken4scholars 你是对的,但是程序已经在 ram 中占用了 20 mb,当我保存对象实例时,它的大小为 5kb,所以我认为我可以在 ram 中而不是在 db 上加载这个实例只是因为它只有 5kb 并且已经花费了 20mb 进行处理。请告诉我这是实现这一目标的正确方法吗?? 【参考方案1】:如果您真的想将游戏状态存储在 RAM 中(尽管 Ken4scholars 在 cmets 中提到了限制),您还可以将共享变量移动到 middleware 中,如下所示:
from channels.middleware import BaseMiddleware
class GameStateMiddleware(BaseMiddleware):
def __init__(self, inner):
self.inner = inner
self.game_states =
async def __call__(self, scope, receive, send):
query = dict((qp.split('=') for qp in scope['query_string'].decode().split("&")))
game_id = query.get('game_id')
if game_id not in self.game_states:
game_states[game_id] =
scope['game_state'] = self.game_states[game_id]
return await super().__call__(scope, receive, send)
在消费者内部,共享变量将在self.scope['game_state']
中可用。由于它是通过引用传递的,因此您也可以对其进行写入,但是,您需要注意同步(例如通过将锁也注入作用域)。
【讨论】:
以上是关于django 频道在组用户之间共享实例变量的主要内容,如果未能解决你的问题,请参考以下文章