【问题标题】:Celery + Channels: receive message in workerCelery + Channels:在工作人员中接收消息
【发布时间】:2020-04-20 09:11:41
【问题描述】:

我正在使用 django 和 celery 构建一种交互式游戏。 Celery 任务正在处理游戏逻辑。

Django/channels 将接收来自游戏 ui 的消息,这些消息需要传递给相同的 celery 任务(每个游戏)。

我还没有找到使用通道向活动 celery 任务发送消息的方法,有什么好的方法吗?

【问题讨论】:

  • 主动芹菜任务?你是什​​么意思?任务像正常功能一样运行。你打电话给他们,他们执行并退出。也许一些代码和更多解释会让你的问题更清楚
  • @Ken4scholars,我的意思是在客户端和 celery worker 之间实现双向通信(中间有通道魔法)。我发现的所有示例都只描述了从工作人员到客户端的通信。

标签: celery django-channels


【解决方案1】:

更新:Turns out that celery 4 doesn't work well with asyncio,所以下面的解决方案不断提高got Future <Future pending> attached to a different loop


我通过在 celery 任务中创建通道找到了一种方法:

tasks.py:

@app.task
def task(channel_name):
    worker_channel_name = async_to_sync(channel_layer.new_channel)()
    async_to_sync(channel_layer.send)(channel_name, {'type': 'ping_pong', 'message': worker_channel_name})
    r = async_to_sync(channel_layer.receive)(channel)

consumers.py:

class Consumer(WebsocketConsumer):

    def receive(self, data):
        ...
        tasks.task.delay(self.channel_name)

    def ping_pong(self, event):
        worker_channel_name = event['message']
        async_to_sync(self.channel_layer.send)(worker_channel_name, ...)

使用它,我可以进一步调用receive,使用获取的worker_channel_name 直接与工作人员通信。

有点不清楚的是我应该将worker_channel_name 存储在客户端还是Consumer 内部(如果后续的websocket 请求位于同一节点上)。

【讨论】:

  • 不是很清楚你想要达到什么。如果您想通过 celery 任务与 cosumer 通信,只需使用 channel_layer.send() 提供频道名称。如果你想从消费者开始一个 celery 任务,那么它就像从任何普通的 python 代码运行一个 celery 任务一样。为什么要在 celery 任务中创建一个新通道?
  • 我想收到更多关于正在进行的 celery 任务的消息。
猜你喜欢
  • 2019-08-15
  • 2017-06-09
  • 2020-03-04
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 2021-08-15
相关资源
最近更新 更多