Следующим шагом является обработка этого сообщения в потребителе на серверной части.
Измените, GroupConsumer как показано ниже:
class GroupConsumer(AsyncWebsocketConsumer):
....
async def receive(self, text_data=None, bytes_data=None):
text_data = json.loads(text_data)
type = text_data.get("type", None)
message = text_data.get("message", None)
author = text_data.get("author", None)
if type == "text_message":
user = await database_sync_to_async(User.objects.get)(email=author)
message = await database_sync_to_async(Message.objects.create)(
author = user,
content = message,
group = self.group
)
await self.channel_layer.group_send(self.group_uuid, {
"type":"text_message",
"message":str(message),
"author":author
})
async def text_message(self, event):
message = event["message"]
author = event.get("author")
returned_data = {
"type":"text_message",
"message":message,
"group_uuid":self.group_uuid
}
await self.send(json.dumps(
returned_data
))
Когда вы отправляете сообщение с помощью group_send метода класса channel_layers, оно вызывает метод класса-потребителя с тем же именем, что и значение ключа типа в сообщении. В этом методе вы можете отправить сообщение с помощью метода self.send().
В модели Group есть методы add_user_to_group и remove_user_from_group, которые вы использовали в методах join_group и leave_group потребителя JoinAndLeaveGroup. Эти методы создают объекты модели Event типа join и leave соответственно для пользователя.
Мы также можем добавить сигналы, чтобы отправить это сообщение о событии во внешний интерфейс, чтобы уведомить пользователей в группе, когда новый пользователь присоединился или вышел.
Создайте файл signals.py в директории приложения chat и добавьте в него следующий код:
from django.dispatch import receiver
from .models import Event
from django.db.models.signals import post_save
from channels.layers import get_channel_layer
from asgiref.sync import async_to_sync
@receiver(post_save, sender=Event)
def broadcast_event_to_groups(sender, instance, **kwargs):
channel_layer = get_channel_layer()
group_uuid = str(instance.group.uuid)
event_message = str(instance)
async_to_sync(channel_layer.group_send)(group_uuid,
{
"type": "text_message",
"message": event_message,
"status": instance.type,
"user": str(instance.user)
}
)
Каждый потребительский класс имеет атрибут channel_layer, к которому мы можем получить доступ внутри потребителя как self.channel_layer. Однако, когда мы находимся вне потребительского класса, например в broadcast_event_to_groups, мы можем получить уровень канала только через функцию get_channel_layer().
Также нам необходимо зарегистрировать сигнал, для этого в файле chat/apps.py изменим код, добавив функцию ready()
from django.apps import AppConfig
class ChatConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'chat'
# new
def ready(self):
import chat.signals