gpt4 book ai didi

django - 在 Django Channels 2 中向群组发送消息

转载 作者:IT王子 更新时间:2023-10-29 05:55:39 27 4
gpt4 key购买 nike

我完全陷入无法使用 Channels 2 进行群组消息传递的困境!我已经按照我能找到的所有教程和文档进行操作,但遗憾的是我还没有找到问题所在。我现在想做的是拥有一个特定的 URL,当访问该 URL 时应该向名为“events”的组广播一条简单的消息。

首先,这里是我在 Django 中使用的相关和当前设置:

CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [('localhost', 6379)],
},
}
}

ASGI_APPLICATION = 'backend.routing.application'

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'channels',
'channels_redis',
'backend.api'
]

接下来,这是我的 EventConsumer,它以非常基本的方式扩展了 JsonWebsocketConsumer。所有这一切都是在收到消息时回显,这很有效!因此,简单的 send_json 响应如期到达,只有群组广播不起作用。

class EventConsumer(JsonWebsocketConsumer):
groups = ["events"]

def connect(self):
self.accept()

def disconnect(self, close_code):
print("Closed websocket with code: ", close_code)
self.close()

def receive_json(self, content, **kwargs):
print("Received event: {}\nFrom: {}\nGroups:
{}".format(content,
self.channel_layer,
self.groups))

self.send_json(content)

def event_notification(self, event):
self.send_json(
{
'type': 'test',
'content': event
}
)

这是我要触发广播的 URL 的 URL 配置:

项目 urls.py

from backend.events import urls as event_urls

urlpatterns = [
url(r'^events/', include(event_urls))
]

事件应用 urls.py

from backend.events.views import alarm

urlpatterns = [
url(r'alarm', alarm)
]

最后,群组广播应该发生的 View 本身:

from django.shortcuts import HttpResponse
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync


def alarm(req):
layer = get_channel_layer()
async_to_sync(layer.group_send)('events', {'type': 'test'})
return HttpResponse('<p>Done</p>')

最佳答案

我在写这个问题时找到了解决方案,并认为其他人也可以使用它!由于此处的大多数问题都是关于 2.0 及更高版本之前的 channel 版本,因此这就是您应该如何处理消费者中的 group_send 事件。

问题不仅在于我如何使用 group_send 函数,我错误地认为将 groups 类变量添加到我的 EventConsumer 应该会自动将它添加到那个/那些组,它确实不是!您必须在 connect 类函数中手动添加组,并在 disconnect 函数中删除组!

问题还在于我的消费者没有指定适当的事件处理程序。在接收警报请求的 View 文件中,我将“类型”设置为“测试”。测试未反射(reflect)在我的 EventConsumer 类中,因此无法处理该事件。如多聊天示例中所述 here在第 146 行,根据发送的事件类型调用辅助函数。因此,'event.alarm' 事件类型在您的消费者中应该具有相应的 event_alarm 功能!简单,但没有很好的记录:)。这是最终解决方案的样子:

consumers.py中,注意connect中的group_add和disconnect中的group_discard!

class EventConsumer(JsonWebsocketConsumer):

def connect(self):
async_to_sync(self.channel_layer.group_add)(
'events',
self.channel_name
)
self.accept()

def disconnect(self, close_code):
print("Closed websocket with code: ", close_code)
async_to_sync(self.channel_layer.group_discard)(
'events',
self.channel_name
)
self.close()

def receive_json(self, content, **kwargs):
print("Received event: {}".format(content))
self.send_json(content)

# ------------------------------------------------------------------------------------------------------------------
# Handler definitions! handlers will accept their corresponding message types. A message with type event.alarm
# has to have a function event_alarm
# ------------------------------------------------------------------------------------------------------------------

def events_alarm(self, event):
self.send_json(
{
'type': 'events.alarm',
'content': event['content']
}
)

因此,上面的函数 events_alarm 从以下 group_send 调用:

from django.shortcuts import HttpResponse

from channels.layers import get_channel_layer

from asgiref.sync import async_to_sync


def alarm(req):
layer = get_channel_layer()
async_to_sync(layer.group_send)('events', {
'type': 'events.alarm',
'content': 'triggered'
})
return HttpResponse('<p>Done</p>')

如果您需要对问题/答案进行更多说明,请告诉我!干杯!

关于django - 在 Django Channels 2 中向群组发送消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48855417/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com