Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用Django通道发送websocket延迟组消息?_Python_Django_Django Channels - Fatal编程技术网

Python 如何使用Django通道发送websocket延迟组消息?

Python 如何使用Django通道发送websocket延迟组消息?,python,django,django-channels,Python,Django,Django Channels,我正在Django频道上创建浏览器游戏。选手必须在1分钟内回答问题。首先,我发送带有问题的事件,然后希望发送带有分钟延迟的消息 我正在使用RedisChannelLayer和JsonWebsocketConsumer class RoomConsumer(JsonWebsocketConsumer): def connect(self): room_name = self.scope['url_route']['kwargs']['room_name']

我正在Django频道上创建浏览器游戏。选手必须在1分钟内回答问题。首先,我发送带有问题的事件,然后希望发送带有分钟延迟的消息

我正在使用RedisChannelLayer和JsonWebsocketConsumer

class RoomConsumer(JsonWebsocketConsumer):
    def connect(self):
        room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'game_' + room_name
        async_to_sync(self.channel_layer.group_add)(self.room_group_name, self.channel_name)
        self.accept()
        self.send_json(connection_event())

    def send_message(self, event):
        self.send_json(event.get('data'))

    def receive_json(self, data, **kwargs):
        try:
            print(data)
            event_type = data.get('eventType')
            if event_type == 'start':
                tasks = []
                ...
                async_to_sync(self.channel_layer.group_send)(self.room_group_name, {
                    'type': 'send_message',
                    'data': start_event(tasks)
                })
                #  here want to send deferred message
        except Exception as e:
            print(e)
计划使用异步睡眠,但需要能够暂停并播放此消息,或者停止并重新发送新的延迟

async def send_delayed_message(self, event):
    await sleep(60)
    await self.send_json(event.get('data'))

你有没有理由在没有停止消费的情况下延迟发送这样的消息?

我会用芹菜来完成这项任务,并使用
共享任务

步骤1:

tasks.py
中编写发送延迟消息的函数:

from celery import shared_task
from channels.layers import get_channel_layer

@shared_task
def send_delayed_message(room_group_name, message):
    channel_layer = get_channel_layer()
    async_to_sync(channel_layer.group_send)(room_group_name, {"type": "send_message", "room_group_name": room_group_name, "message": {"message": message})
步骤2:

将延迟属性添加到数据对象:

data["delay"] = 60 #in seconds
步骤3:

使用延迟属性从RoomConsumer调用函数:

async def send_delayed_message(self, event):
    data = event.get("data")
    message = data.get("message")
    room_id = self.room_group_name
    delay = data.get("delay")
    if delay:
        task = await send_delayed_message.apply_async(args=[room_id, message], countdown=delay)
        return task
步骤4:

与其“暂停”任务,不如结束任务并重新发送相同的消息。暂停和停止的逻辑相同

from proj.celery import app

def end_celery_message(task_id):
    app.control.revoke(task_id, terminate=True)

谢谢你的回答!但是这个解决方案不能暂停/恢复,或者干脆停止。我会在我的答案中添加一个解决方案。