Рубрики
Без рубрики

Каналы Django – простое чат приложение Part 3

Привет всем 👋 Извиняюсь за задержку этой статьи. Это заключительная часть серии. К… Теги с Python, Django, WebDev, учебником.

Каналы 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”