Как добавить уведомления в реальном времени с помощью Django и nextjs


Введение

Django и по сей день является проверенным в боях веб-фреймворком, построенным на одном из самых любимых языков программирования — -Python. Его многофункциональный фреймворк имеет встроенную поддержку таких важных и критических вещей, как аутентификация пользователей, безопасность, мощный ORM (Object Relational Mapper), встроенную панель администратора, формы и многое другое, уже встроенное в фреймворк.

Но если мы вернемся к первым дням создания Django, то тогда едва ли существовало понятие микросервисов и архитектуры, основанной на событиях. Монолитные стеки были популярны с небольшими нахальными штрихами, чтобы стек соответствовал сложным требованиям того времени.

Но сегодня веб-приложения гораздо более модульные. У нас есть отличные фронтенд-фреймворки, такие как React, Vue, Svelte и т.д., обеспечивающие гораздо лучший UI/UX, чем шаблоны. Мир уменьшился, и теперь всем нужен опыт работы в реальном времени, когда речь идет о веб-приложениях. Больше никаких обновлений. Никаких обновлений. Я хочу изменений в реальном времени!

Но Django никогда не был создан для работы в реальном времени, например, с сокетами, опросом и т.д. Несомненно, у нас есть такие решения, как Django channels, а также технологии вроде celery для решения этой проблемы. Но это тоже сопровождается дополнительными проблемами, такими как:

  • Сложность — лозунг Django «Веб-фреймворк для перфекционистов со сроками» становится несвежим.
  • Масштабируемость — Масштабирование системы реального времени само по себе является сложной задачей. В сочетании с необходимостью строить на технологиях, которые изначально для этого не предназначались, это становится сверхсложной задачей.

🎉 Давайте решим проблему

В этой статье я покажу вам, как вы можете добавить любую функциональность реального времени в ваше Django-приложение, сохранив при этом минимальную сложность и время на реализацию.
Здесь я использую PubNub для добавления функций уведомления в базовое приложение для социальных сетей, которое я создал в качестве демонстрации. Если вы хотите взглянуть на кодовую базу, то вам сюда! 👇

mabdullahadeel / django-pubnub-notifications

Реализация pubnub с django для доставки уведомлений пользователям в реальном времени

DJ PubNub

Это простое приложение для социальных сетей, созданное на основе django и nextjs с функцией уведомлений в реальном времени на основе PubNub.


Посмотреть на GitHub

Live App 👇

https://django-pubnub.vercel.app

PubNub работает в этом бизнесе уже очень давно, и их инфраструктура достаточно развита, чтобы справиться с пользовательской базой любого размера, а также у них есть очень щедрый бесплатный уровень 😉. Кроме того, вы можете либо использовать их REST API для всего, либо использовать их SDK. SDK доступны практически для всех серверных языков.

Описание приложения

Это базовое приложение для социальных сетей. Пользователь может зарегистрироваться, используя свой email и пароль. Создавать/редактировать свои посты. Пользователи могут комментировать посты. Каждый раз, когда создается новый комментарий, владельцу поста отправляется уведомление.

👩💻 Технический стек

  • Django (веб-сервер)
  • Django REST framework (API)
  • PostgreSQL
  • PubNub (для уведомлений в реальном времени)
  • Nextjs (фронтенд)

Нажмите, чтобы увидеть полную диаграмму

Логика сервера

На сервере я создал базовые модели Post и Comment в файле users/models.py. CRUD Rest API обрабатываются с помощью django restframework . Довольно базовые обработчики маршрутов используют общие представления и сериализатор моделей.

В server/core/pubnub/pubnub_service.py я создал базовый класс утилиты, который открывает две основные функции из PubNub’s python SDK. Во-первых, когда пользователь входит в систему, для каждого пользователя должен быть создан секретный токен, чтобы он мог безопасно подключиться к PubNub. Эти токены авторизации гарантируют, что только клиенты, авторизованные для доступа к каналу, могут читать сообщения из этого канала.


import logging

from django.conf import settings
from pubnub.models.consumer.v3.channel import Channel
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.exceptions import PubNubException

from users.models import User

logger = logging.getLogger(__name__)

pnconfig = PNConfiguration()

pnconfig.publish_key = settings.PUBNUB_PUBLISH_KEY
pnconfig.subscribe_key = settings.PUBNUB_SUBSCRIBE_KEY
pnconfig.secret_key = settings.PUBNUB_SECRET
pnconfig.uuid = settings.SERVER_PUBNUB_UUID

pubnub = PubNub(pnconfig)

class PubNubService:
    DEFAULT_NOTIFICATION_TTL = 60 # 60 minutes

    @staticmethod
    def get_notification_token_for_user(user: User, ttl: int = DEFAULT_NOTIFICATION_TTL):
        envalope = pubnub.grant_token() 
            .channels([Channel.id(user.get_notification_channel_name()).read().delete()]) 
            .ttl(ttl) 
            .authorized_uuid(user.get_notification_channel_name()) 
            .sync()
        token = envalope.result.token
        token_payload = pubnub.parse_token(token)

        return {
            "exp_timestamp": token_payload["timestamp"],
            "token": token,
            "ttl": token_payload["ttl"],
        }

    @staticmethod
    def send_notification_to_user(user: User, message):
        try:
            pubnub.publish() 
            .channel(user.get_notification_channel_name()) 
            .message(message) 
            .use_post(use_post=True) 
            .sync()
        except PubNubException as e:
            logger.error(e)

Вход в полноэкранный режим Выход из полноэкранного режима

Здесь я создаю канал PubNub для каждого пользователя. Имя этого канала — UUID пользователя, идентифицированного custom get_notification_channel_name . Когда пользователь входит в мое Django приложение, только ему будет предоставлен токен для доступа к каналу уведомлений, связанному с его уникальным идентификатором. Таким образом, каждый пользователь получает уведомления, предназначенные для него.

Каналы — это основа работы PubNub. Ваше приложение может создавать столько каналов PubNub, сколько ему необходимо. Фактически, всякий раз, когда вы указываете канал в запросе, если он еще не существует, он будет создан перед помещением сообщения в канал.

Сигналы Django используются для обнаружения событий сохранения комментариев, и при успешном сохранении комментария пользователю отправляется уведомление через функцию-приемник сигнала. Это так просто! Вот простая функция-приемник.


import logging
from uuid import uuid4

from .models import Comment
from django.db.models.signals import post_save
from django.dispatch.dispatcher import receiver
from core.pubnub.pubnub_service import PubNubService

logger = logging.getLogger(__name__)

@receiver(post_save, sender=Comment)
def create_comment_notification(sender, instance: Comment, created, **kwargs):
    post = instance.post
    author = post.author
    commenter = instance.user
    if created and author != commenter:
        message = {
            "message": f'{commenter.username} commented on your post.',
            "peek": f'{instance.text[0:10]}...',
            "id": str(uuid4())[0:8],
            "pid": str(post.id),
        },
        PubNubService.send_notification_to_user(user=author, message=message)
        logger.warn("Notification sent to user: %s", author.username)
Вход в полноэкранный режим Выход из полноэкранного режима

Заключение

Этот подход не ограничивается только отправкой уведомлений, вы можете расширить его до сложных функций, таких как чаты в реальном времени, лайки и т.д. Вы уловили суть. Это разгружает PubNub от обработки соединений в реальном времени. На мой взгляд, стоимость также вполне сопоставима. Если вы будете заниматься всем этим самостоятельно, вашей команде придется кодировать весь стек соединений в реальном времени, что требует времени и ресурсов. Кроме того, теперь ваша команда должна позаботиться о тестировании, поддержке и масштабировании другой инфраструктуры, что также потребует еще больше ресурсов. Но эта статья должна дать вам хорошее представление о том, какой путь вы хотите выбрать.

Если вам понравилось то, что вы только что прочитали, не забудьте следить за мной в Twitter 🐤, LinkedIn и Youtube. Я делюсь статьями вместе с рабочими примерами и вставками, чтобы вам было удобнее читать/обучаться.
Вот ссылка на приложение, если вы хотите поиграть с ним.

👉 https://django-pubnub.vercel.app

До встречи! 👋

Оцените статью
devanswers.ru
Добавить комментарий