Каналы Django – добавьте поддержку веб-сокета в ваш проект Django (4 части серии)
Привет всем 👋.
Извиняюсь за задержку этой статьи. Это заключительная часть серии. К концу этого учебника у нас будет простой чат-сервер в нашей руке.
В последней части этой серии мы открыли подключение Websocket, но ничего не произошло, потому что каналы не знают, где смотреть, чтобы обрабатывать/принимать соединение. Похоже на Виды В Django, который принимает/обрабатывать HTTP-запрос, у нас есть что называется Потребители в каналах.
Существует два типа потребителей WebSocket. Asyncconsumer
и Syncconsumer
Отказ Первый давайте пишем ASYNC-CODE, а последний используется для записи синхронного кода.
Что использовать, когда?
- Использовать
Asyncconsumers
Для большей производительности и при работе с независимыми задачами, которые можно сделать параллельно, в противном случае придерживатьсяSynccconsumers
Отказ Для этой руководства мы будем писатьSynccconsumers
Отказ
Тем не менее, написание только потребителей не достаточно. Мы хотим, чтобы несколько экземпляров потребителей смогут говорить друг с другом. Это делается с использованием слоев канала. В моей последней статье я говорил о слоях каналов и как настроить его так, если вы еще не сделаете, не пройдете и проверьте это.
Канальный слой имеет следующее:
1) Канал – это почтовый ящик, в котором могут быть отправлены сообщения. У каждого канала есть имя. Любой, у кого есть имя канала, может отправить сообщение на канал.
- Но в тех случаях, когда мы хотим прислать нескольким каналам/потребителям одновременно, нам нужна какая-то широковещательная система. Вот почему у нас есть что называется Группы Отказ
2) Группа – Группа связанных каналов. У группы есть имя. Любой, у кого есть имя группы, может добавлять/удалить канал в группу по имени и отправить сообщение на все каналы в группе.
Мы можем использовать группы, добавляя канал к ним во время подключения и удалением его во время отключения. Как это: channel_layer.group_add
и channel_layer.group_discard.
. Не волнуйтесь, так как мы собираемся увидеть все эти концепции в действии.
Поскольку эта серия все о начале работы с каналами Django, мы собираемся создать базовый потребитель, который слушает сообщения в подключении WebSocket и откроет его обратно к тому же соединению.
Создайте новый файл под названием Потребители.пи Внутри приложения чата и положите следующее.
Чат/Потребители
import json from asgiref.sync import async_to_sync from channels.generic.websocket import WebsocketConsumer class ChatConsumer(WebsocketConsumer): def connect(self): self.room_name = self.scope['url_route']['kwargs']['room_name'] self.room_group_name = 'chat_%s' % self.room_name # Join room group async_to_sync(self.channel_layer.group_add)( self.room_group_name, self.channel_name ) self.accept() def disconnect(self, close_code): # Leave room group async_to_sync(self.channel_layer.group_discard)( self.room_group_name, self.channel_name ) # Receive message from WebSocket def receive(self, text_data): text_data_json = json.loads(text_data) message = text_data_json['message'] # Send message to room group async_to_sync(self.channel_layer.group_send)( self.room_group_name, { 'type': 'chat_message', 'message': message } ) # Receive message from room group def chat_message(self, event): message = event['message'] # Send message to WebSocket self.send(text_data=json.dumps({ 'message': message }))
WebsocketConsumer
который доступен отканалы .generic.websocket
является базовым потребителем WebSocket. Он синхронно и обеспечивает общую инкапсуляцию для модели обработки WebSocket, что могут построить другие приложения.-
Asgiref
Пакет, который включает в себя базовые библиотеки ASGI, такие какSync-Async
иasync-to-sync
Функциональные обертки автоматически устанавливаются как зависимость при установке Django с PIP. Как это будет полезно? Рад, что вы спросили. - Все методы канального слоя являются асинхронными, но наш потребитель, который мы назвали
Chatconsumer
синхронноWebsocketConsumer
Отказ Вот почему нам нужно обернуть методы канала слоя вasync-to-sync
Функция, предоставленная изAsgiref.sync.
модуль. Эта функция обертки принимает ASYNC функцию и возвращает функцию синхронизации. - Любой потребитель имеет
self.channel_layer
иself.channel_name
атрибут, который содержит указатель на экземпляр канала и имя канала соответственно. - Наш самый собственный
Chatconsumer
наследует от базового класса,WebsocketConsumer
и используйте его методы класса, чтобы сделать следующее:
1) Подключиться ()
Способ => Как на имя подразумевается, что он называется, когда подключение WebSocket открывается. Внутри этого метода мы впервые получили Room_Name
Параметр из маршрута URL в Чат/Маршрут .py Это открыло подключение Websocket с потребителем. Этот параметр доступен из Область из потребительского экземпляра.
- Область Содержит много информации, связанной с соединением, что экземпляр потребителя в настоящее время включен. Подумайте об этом как о виде информации, которую вы найдете на объекте запроса в представлении Django. Это от этой области, что мы можем получить аргумент ключевых слов (
Room_Name
) с маршрута URL. Self.room_Group_name% Self.room_name
Что это делает, это создает название группы каналов непосредственно из указанного пользователем имени комнаты.async_to_sync (self.channel_layer.group_add) (...)
присоединяется к группе комнаты. По причинам, по которым я упомянул ранее, эта функция завернута вasync-to-sync
функция.self.Accept ()
принимает входящий разъем.
2) Отключить ()
Способ => называется, когда подключение WebSocket закрыто.
async_to_sync (self.channel_layer.group_discard) (...)
оставляет группу.
3) получить ()
Метод => называется с декодированной рамкой WebSocket. Мы можем отправить либо text_data
или bytes_data
для каждого кадра.
json.loads (text_data)
разбирается в строке JSON (входное сообщение пользователя), которое отправляется через соединение от Room.html и преобразует его в словарь Python.text_data_json ['Сообщение']
Захватывает это сообщение.async_to_sync (self.channel_layer.group_send)
События по слою канала. Событие имеет специальноеТип
Ключ, который соответствует названию метода, который следует вызывать на потребителях, которые получают мероприятие. Мы устанавливаем этот тип типа как«Тип»: «Chat_Message»
поэтому мы ожидаем, что мы будем объявлять функцию обработки с именемChat_Message
Это получит эти события и превратит их в рамы Websocket.
Примечание : Имя метода будет тот тип события со сроками, заменяемыми подчеркивающими, – так, например, событие, происходящее над уровнем канала с типом Chat.join
будет обрабатываться методом Chat_join
Отказ
4) chat_message ()
метод => Обрабатывает Chat.message
событие, когда он отправлен нам. Это получает сообщения из группы комнаты через событие [«сообщение»]
и отправьте его к клиенту.
Потребители объяснили в двух словах. Обратитесь к документации для получения дополнительной информации.
Похож на то, как Django имеет Urls.py. у этого есть маршрут к Просмотр .py Каналы имеют Routing.py у этого есть маршрут к Потребители.пи Отказ Поэтому продолжайте и создайте Routing.py Внутри приложения чата и положите следующий код.
routing.py
from django.urls import re_path from . import consumers websocket_urlpatterns = [ re_path(r'ws/chat/(?P\w+)/$', consumers.ChatConsumer.as_asgi()), ]
AS_ASGI ()
Метод похож наAS_View ()
Метод, который мы вызываем при использовании классовых представлений. Что это делает, это возвращает приложение ASGI Wrapper, которое будет создавать новый экземпляр потребителя для каждого соединения или объема.
Далее, отправляйтесь на Asgi.py и изменить это следующим образом.
asgi.py
import os from channels.auth import AuthMiddlewareStack from channels.routing import ProtocolTypeRouter, URLRouter from django.core.asgi import get_asgi_application import chat.routing os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings") application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( chat.routing.websocket_urlpatterns ) ), })
- Приведенный выше код указывает на конфигурацию корневой маршрутизации к
Chat.Rooting
модуль. Это означает, что когда соединение сделано на сервер разработки (сервер развития канала),Протоколтиспертер
Проверяет, является ли это нормальный HTTP-запрос или веб-сайт. - Если это Websocket,
Authmiddlewarestack
Отмечу оттуда и заполнит объем соединения со ссылкой на текущий аутентифицированный пользователь, похожий на «Django»Аутентификация Moddleware
заполняетзапрос
ОбъектВид
Функция с текущим аутентифицированным пользователем. - Далее
Urllouter
Обведите соединение с определенным потребителем на основе предоставленных узоров URL.
Хорошо, запустите сервер разработки,
python manage.py runserver
Откройте вкладку браузера, введите имя комнаты, которую вы хотели бы присоединиться и открыть его на другой вкладке.
В одном из вкладок введите любую нужное сообщение, нажмите Enter и перейдите на другую вкладку. Вы должны увидеть сообщение, транслируемое в обоих вкладках. Это приносит нам до конца этой серии.
Ссылка – https://channels.readthedocs.io/en/stable/
Я надеюсь, что вы смогли получить основную картину того, как все это работает и используют его в следующем проекте. Спасибо за ваше время и отзывы 👋
Каналы Django – добавьте поддержку веб-сокета в ваш проект Django (4 части серии)
Оригинал: “https://dev.to/earthcomfy/django-channels-a-simple-chat-app-part-3-a3b”