【问题标题】:Django - How to share data between ASGI and WSGI applications?Django - 如何在 ASGI 和 WSGI 应用程序之间共享数据?
【发布时间】:2020-04-13 00:23:56
【问题描述】:

我在 Django 上制作我的项目,它在 WSGI 上有 Gunicorn,在 ASGI 上有 Daphne。 ASGI 服务器仅用于处理 Websocket 协议。在 Django 中使用 Channels 进行 Websocket 路由和处理。静态和代理上的 Nginx。数据库是Mysql。

一般情况:有没有办法在不写入数据库的情况下在 ASGI 和 WSGI 应用程序之间同步内存中的变量值?

TLDR:

HTTP (wsgi) 主要用于与数据库交互(目前,创建模型实例)。

Websocket (asgi) 计划与用户控件一起使用(现在,连接到房间,将来,将是游戏内控件?旋转块等。该项目是俄罗斯方块多人游戏,例如,用户可以在其中创建房间,对于 2 或 4 名玩家(平行俄罗斯方块场),创建时其他玩家可以连接到该房间。)

'Under the hood' 有'engine'(一些数据在服务器运行时存储在内存中):

# engine/status.py
active_rooms = {}

创建新房间时,HTTP 控制器(来自 views.py)调用函数:

import engine.status as status
from engine.Room import Room

def create_room(id, size):
    new_room = Room(size)

    ...

    status.active_rooms[id] = new_room

    ...

因此,它将一个新的键值对写入 dict (status.active_rooms),其中键是数字(id),值是类 'Room' 的实例。

当其他玩家点击房间中的“连接”按钮时,客户端上的 Javascript 通过 Websocket 协议发送特殊消息。 Websocket 处理程序调用函数:

def make_connect(data):
    id = data['room_id']
    ...
    if int(id) not in status.active_rooms:
        msg = 'No room'
        return {'type': 'info', 'msg': msg}
    else:
        msg = 'Room exists'
        ...

因此它会检查内存中是否存在具有此 ID 的房间。 问题是: 检查时字典总是空的! 似乎 ASGI 和 WSGI 应用程序都有自己的“引擎”实例。 这意味着,客户端无法看到服务器上的实际状态。

我尝试将转储转储到数据库中,但该类有一些无法腌制的特定字段。 我现在的想法是,用 ASGI 应用程序“创建房间”(通过 Websocket 而不是 HTTP)。 也许我错过了什么?还有其他方法可以在 ASGI 和 WSGI 应用程序之间共享数据吗?

【问题讨论】:

    标签: django websocket asgi


    【解决方案1】:

    仅供参考:我设法在 HTTP 请求的同时发出 WS 并行请求。

    WSGI 应用程序写入 DB,ASGI 应用程序在内存中创建具有特定键的对象,这些键可用于访问 DB 中的数据。

    在下一个 WS 请求时,ASGI 从内存中的这些对象中读取键并调用从 DB 加载数据的函数。总的来说,ASGI 和 WSGI 没有使用相同的环境,但是在第一次并行 HTTP 和 WS 请求中使用相同的唯一键,ASGI 可以访问 WSGI 接收到的数据

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-05
      • 2019-03-29
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 2018-11-14
      相关资源
      最近更新 更多