如何使用 Django Channels 3.0.0 向所有消费者发送消息?

How to send a message to all consumers using Django Channels 3.0.0?

我正在尝试开发一个界面,其中包含一个显示所有活跃用户的部分。因此,当用户连接到 WebSocket 时,我想将数据发送给所有连接的消费者。

目前,我编写了一段代码,当用户连接时,它只向连接的用户发送数据。我想以某种方式将消息发送给所有活动 users/consumers.

这是我的 WebSocket 的路径 handler/view

path('test_ws/', websocket.TestConsumer.as_asgi()),

这是处理程序

class NewsMentionConsumer(AsyncWebsocketConsumer):

groups = ["newsmention1"]
channel_name = 'news_mention'
active_users = []

async def connect(self):
    await self.channel_layer.group_add(self.groups[0], self.channel_name)
    await self.channel_layer.group_send(self.groups[0], {
        'type': 'send_updates',
        'text': json.dumps({
            'id': self.scope['user'].id,
            'username': self.scope['user'].username,
            'active_users': self.active_users
        })
    })
    await self.accept()
    self.active_users.append(self.scope['user'])

async def send_updates(self, event):
    # TODO: Make this send to all users/consumers
    await self.send(event["text"])

我在理解 django.channels 文档中的示例时遇到问题,并尝试使用 send_group 函数,但它并没有真正起作用。有什么建议吗?

编辑:将所有用户添加到具有唯一名称的同一组。

async def connect(self):
    await self.channel_layer.group_add(self.groups[0], self.unique_name());
    await self.channel_layer.group_send(self.groups[0], { ... });

group_send 仍然只向请求的用户发送消息。

编辑 2:添加初始化函数后。

现在,我有一个 channel_name,但是当我尝试将数据发送给组中的所有消费者时出现新错误:

class NewsMentionConsumer(AsyncWebsocketConsumer):

group = "newsmention1"
active_users = []

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)

async def connect(self):
    await self.channel_layer.group_add(
        self.group,
        self.channel_name,
    )

    await self.channel_layer.group_send(self.group, {
        'type': 'send_updates',
        'id': self.scope['user'].id,
        'username': self.scope['user'].username,
        'some_data_to_all_clients': some_data_to_all_clients()
    })

async def disconnect(self, close_code):
    await self.channel_layer.group_discard(self.group, self.channel_name)

async def send_updates(self, event):
    await self.channel_layer.send_group(self.group, event)


'RedisChannelLayer' object has no attribute 'send_group'

有什么建议吗?

编辑 3:

    async def connect(self):
        await self.accept()
        await self.channel_layer.group_add(
            self.group,
            self.channel_name,
        )
        self.active_users.append({
            'id': self.scope['user'].id,
            'username': self.scope['user'].username
        })
        await self.channel_layer.group_send(self.group, {
            'type': 'send_updates',
            'id': self.scope['user'].id,
            'username': self.scope['user'].username,
            'some_data_to_all_clients': some_data_to_all_clients()
        })

    async def send_updates(self, event):
        await self.send(json.dumps(event))

您不应设置静态频道名称,因为它用于标识频道,因此必须是唯一的。通常的做法是使用 Django Channels 生成的频道名称。 关于向所有连接的用户发送事件,您只需要有一个组,您可以在所有通道连接时将其添加到该组,然后将消息发送到那里。除了频道名称部分,您所做的看起来已经很相似了。

This is a bug 个 Django 频道 3.0.0。它已在 3.0.1.

中修复