Приложение для чата в реальном времени с использованием Django

Опубликовано: 14 Декабря, 2022

Чат был самым основным шагом к созданию проектов в реальном времени и в реальном времени. Страница чата, которую мы создадим, будет представлять собой простой HTML-шаблон с простым текстом h1 с именем текущего пользователя и ссылкой для выхода для пользователя, который только что вошел в систему. Возможно, вам придется прокомментировать строку, пока мы создать систему авторизации для этого. Это гарантирует, что когда два пользователя общаются в чате, один может выйти из системы, и это не повлияет на другого пользователя. Другой будет по-прежнему входить в систему, и он может отправлять и получать сообщения.

Предпосылки:

  • Джанго
  • Джанго Миграции
  • Канал Джанго

Введение в каналы Django и асинхронное программирование

Каналы — это проект Python, который был создан для расширения возможностей Django на новый уровень. Мы работали в стандартном Django, который не поддерживал асинхронность, каналы и подключение через WebSockets для создания приложений реального времени. Каналы расширяют возможности Django за пределы HTTP и заставляют его работать с WebSockets, протоколами чата, протоколами IoT и т. д. Он построен на поддержке ASGI, что означает интерфейс шлюза асинхронного сервера. ASGI является преемником WSGI, который обеспечивает интерфейс между async и python. Каналы обеспечивают функциональность ASGI, расширяя к нему WSGI, и он обеспечивает поддержку ASGI с WSGI. Каналы также связывают архитектуру, управляемую событиями, с уровнями каналов, системой, которая позволяет легко взаимодействовать между процессами и разделять ваш проект на разные процессы.

Шаги для создания приложения чата

Шаг 1: Установите и настройте Django

Шаг 2: Создайте свою виртуальную среду.

Шаг 3: Затем создайте проект Django с именем ChatApp. Для создания проекта напишите команду в своем терминале.

django-admin startproject ChatApp

Шаг 4: После создания проекта структура папок должна выглядеть так, а затем откройте свою любимую IDE для дальнейшей работы.

Шаг 5: Установите django-каналы для работы с чат-приложением. Это установит каналы в вашу среду.

python -m pip install -U channels

Шаг 6: После установки каналов добавьте каналы в установленные приложения. Это сообщит Django, что в проекте появились каналы и мы можем работать дальше.

Python3




INSTALLED_APPS = [
    "chat.apps.ChatConfig",
     
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
     
    # add django channels
    "channels" ,
]

Шаг 7: Установите для приложения ASGI файл ASGI по умолчанию в проекте. Теперь запустите сервер, вы заметите, что сервер ASGI будет размещаться над сервером Django, и теперь он будет поддерживать ASGI.

Python3




ASGI_APPLICATION = "ChatApp.asgi.application"

Чтобы запустить сервер, напишите в терминале следующую команду.

Python3




python manage.py runserver

Шаг 8: Создайте новое приложение со всеми функциями чата. Чтобы создать приложение, напишите команду в терминале.

python manage.py startapp chat

И добавьте свое приложение к установленным приложениям в settings.py.

Шаг 9. Создайте несколько файлов в приложении чата.

  • chat/urls.py: Это направит приложение Django на разные представления в приложении.
  • Создайте папку шаблонов: внутри вашего приложения создайте два файла внутри шаблона/чата с именами chat.Page.html и LoginPage.html.
  • routing.py: это направит соединения WebSocket к потребителям.
  • Consumer.py: это файл, в котором будут выполняться все асинхронные функции.

Вставьте этот код в ваше приложение ChatApp/urls.py. Это перенаправит вас в приложение чата.

Python3




from django.contrib import admin
from django.urls import path, include
 
urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("chat.urls")),
]

Вставьте этот код в свой чат/urls.py. Это направит вас к просмотрам.

Python3




from django.urls import path, include
from chat import views as chat_views
from django.contrib.auth.views import LoginView, LogoutView
 
 
urlpatterns = [
    path("", chat_views.chatPage, name="chat-page"),
 
    # login-section
    path("auth/login/", LoginView.as_view
         (template_name="chat/LoginPage.html"), name="login-user"),
    path("auth/logout/", LogoutView.as_view(), name="logout-user"),
]

Вставьте этот код в свой views.py. Это направит ваши представления на страницу chatPage.html, созданную в папке шаблонов приложения чата.

Python3




from django.shortcuts import render, redirect
 
 
def chatPage(request, *args, **kwargs):
    if not request.user.is_authenticated:
        return redirect("login-user")
    context = {}
    return render(request, "chat/chatPage.html", context)

URL-адрес находится в формате Django, это синтаксис Django для сопоставления с URL-адресом. Мы создадим URL-адрес с именем «logout-user», затем Django сопоставит это имя URL-адреса с URL-адресом из шаблона. Django предоставляет несколько pythonic-синтаксисов для работы с оператором управления. Здесь мы предоставили строку {% if request.user.is_authenticated %} в HTML, это предоставляется Django, который гарантирует, что если есть какой-либо пользователь, который вошел в систему, то отображается только ссылка для выхода.

  • шаблоны/чат/chatPage.html

HTML




<!DOCTYPE html>
<html>
  <body>
    <center><h1>Hello , Welcome to my chat site ! {{request.user}}</h1></center>
    <br>
    {% if request.user.is_authenticated  %}
    <center> Logout the chat Page <a href = "{% url "logout-user" %}">Logout</a></center>
    {% endif %}
    <div
      class="chat__item__container"
      id="id_chat_item_container"
      style="font-size: 20px"
    >
      <br />
      <input type="text" id="id_message_send_input" />
      <button type="submit" id="id_message_send_button">Send Message</button>
      <br />
      <br />
    </div>
    <script>
      const chatSocket = new WebSocket("ws://" + window.location.host + "/");
      chatSocket.onopen = function (e) {
        console.log("The connection was setup successfully !");
      };
      chatSocket.onclose = function (e) {
        console.log("Something unexpected happened !");
      };
      document.querySelector("#id_message_send_input").focus();
      document.querySelector("#id_message_send_input").onkeyup = function (e) {
        if (e.keyCode == 13) {
          document.querySelector("#id_message_send_button").click();
        }
      };
      document.querySelector("#id_message_send_button").onclick = function (e) {
        var messageInput = document.querySelector(
          "#id_message_send_input"
        ).value;
        chatSocket.send(JSON.stringify({ message: messageInput, username : "{{request.user.username}}"}));
      };
      chatSocket.onmessage = function (e) {
        const data = JSON.parse(e.data);
        var div = document.createElement("div");
        div.innerHTML = data.username + " : " + data.message;
        document.querySelector("#id_message_send_input").value = "";
        document.querySelector("#id_chat_item_container").appendChild(div);
      };
    </script>
  </body>
</html>

{{request.user.userrname}} сообщает имя пользователя, вошедшего в систему в данный момент. Если пользователь вошел в систему, он даст свое имя пользователя; если он не вошел в систему, он ничего не напечатает. Страница чата теперь выглядит так, потому что нет текущего пользователя, вошедшего в систему, и {{request.user.username}} ничего не выводит.

  • шаблоны/чат/LoginPage.html

HTML




<!DOCTYPE html>
<html>
<body>
    <form method ="post">
        {% csrf_token %}
        {{form.as_p}}
        <br>
        <button type = "submit">Login</button>
    </form>
</body>
</html>

Реализовать WebSockets, асинхронные каналы и каналы Django.

До сих пор мы настроили наш стандартный проект Django. После внедрения приложения Django. Теперь пришло время создать приложение ASGI.

Шаг 10: Сначала перенесите базу данных.

python manage.py makemigrations
python manage.py migrate

Шаг 11: Откройте файл routing.py и создайте маршрут для ChatConsumer (который мы создадим на следующем шаге). Теперь у нас есть два типа маршрутизации в проекте. Во-первых, это urls.py, который предназначен для собственной маршрутизации URL-адресов Django, а другой — для поддержки WebSockets для ASGI Django.

чат/routing.py

Python3




from django.urls import path , include
from chat.consumers import ChatConsumer
 
# Here, "" is routing to the URL ChatConsumer which
# will handle the chat functionality.
websocket_urlpatterns = [
    path("" , ChatConsumer.as_asgi()) ,
]

Шаг 12 . Open Consumers.py будет обрабатывать события, такие как событие onmessage, событие onopen и т. д. Мы увидим эти события в файле chatPage.html , где мы создали подключение к сокету.

Объяснение кода:

  • class ChatConsumer(AsyncWebsocketConsumer): здесь мы создаем класс с именем ChatConsumer, который наследуется от AsyncWebsocketConsumer и используется для создания, уничтожения и выполнения некоторых других действий с WebSockets. И вот мы создаем ChatSocket для нужной цели.
  • async def connect(self): эта функция работает с экземпляром веб-сокета, который был создан, и когда соединение открыто или создано, оно подключается и принимает соединение. Он создает имя группы для чата и добавляет группу в группу слоя канала.
  • async def disconnect(): это просто удаляет экземпляр из группы.
  • async def receive(): эта функция запускается, когда мы отправляем данные из WebSocket (событие для этого: send), она получает текстовые данные, которые были преобразованы в формат JSON (так как это подходит для javascript ) после получения text_data его необходимо распространить на другие экземпляры, которые активны в группе. мы извлекаем параметр сообщения, который содержит сообщение, и параметр имени пользователя, который был отправлен сокетом через HTML или js. Это полученное сообщение будет распространено на другие экземпляры с помощью метода channel_layer.group_send(), который принимает первый аргумент в качестве roomGroupName, к какой группе принадлежит этот экземпляр и куда необходимо отправить данные. тогда второй аргумент — это словарь, который определяет функцию, которая будет обрабатывать отправку данных («type»: «sendMessage»), а также словарь имеет переменную message, которая содержит данные сообщения.
  • async def sendMessage(self, event): эта функция принимает экземпляр, который отправляет данные и событие, в основном событие содержит данные, которые были отправлены с помощью метода group_send() функции receive(). Затем он отправляет сообщение и параметр имени пользователя всем экземплярам, активным в группе. И он выгружается в формате JSON, чтобы js мог понять нотацию. JSON - это формат (обозначение объекта Javascript)

чат/consumers.py

Python3




import json
from channels.generic.websocket import AsyncWebsocketConsumer
 
class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.roomGroupName = "group_chat_gfg"
        await self.channel_layer.group_add(
            self.roomGroupName ,
            self.channel_name
        )
        await self.accept()
    async def disconnect(self , close_code):
        await self.channel_layer.group_discard(
            self.roomGroupName ,
            self.channel_layer
        )
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json["message"]
        username = text_data_json["username"]
        await self.channel_layer.group_send(
            self.roomGroupName,{
                "type" : "sendMessage" ,
                "message" : message ,
                "username" : username ,
            })
    async def sendMessage(self , event) :
        message = event["message"]
        username = event["username"]
        await self.send(text_data = json.dumps({"message":message ,"username":username}))

ChatConsumer, который мы отображаем в файле routing.py, такой же, как и в этом Consumer.py, который мы только что создали. Эти сценарии находятся в асинхронном режиме, поэтому мы работаем с асинхронным режимом и ждем здесь.

Шаг 13: Напишите приведенный ниже код в файле asgi.py, чтобы заставить его работать с сокетами и создавать маршруты.

Приложение Чат/asgi.py

Python3




import os
from django.core.asgi import get_asgi_application
 
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ChatApp.settings")
 
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter , URLRouter