Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

8.6 Работа с WebSocket
5 из 5 шагов пройдено

Следующий шаг — заставить работать кнопки домашней страницы. Когда пользователь нажимает кнопку «Покинуть», он должен покинуть связанную группу. Event Затем в бэкэнде создается объект «выход» .

Когда пользователь нажимает кнопку Join, он добавляется в группу и создается объект события присоединения.

Добавьте на страницу chat/home.html следующий JS-скрипт:

{% block script %}
    <script>
        base_url = `${window.location.hostname}:${window.location.port}`
        const websocket = new WebSocket(`ws://${base_url}`)

        websocket.onopen = function (event) {
            console.log('client says connection opened')
            websocket.send("Client sends Welcome")
        }

        websocket.onmessage = function (event) {
            console.log("client says server message received: ", event)
        }


        function add_event_to_all_buttons() {
            /* Добавим прослушиватель событий, который отправляет сообщение о событии на все кнопки */
            const keys = document.querySelectorAll('.group_option');
            keys.forEach(item => {
                    item.addEventListener('click', send_event_message)
                }
            )
        }


        function send_event_message(event) {
            /* Отправим uuid и значение кнопки, которая была нажата */
            const {target} = event;
            group = target.value.split(" ")
            group_uuid = group[1]
            action = group[0] //Leave or Join or Open
            if (action == "open_group") {
                window.location.replace(`http://${base_url}groups/${group_uuid}/`)
            } else {
                data = {
                    "type": action,
                    "data": group_uuid,
                }
                websocket.send(JSON.stringify(data))
            }
        }

        add_event_to_all_buttons()

    </script>
{% endblock script %}


Когда пользователь нажимает кнопку, клиент вызывает функцию send_event_message и отправляет значение uuid группы на сервер:

Мы указали как type:action которое мы берем из значения кнопки, нажатой пользователем. Действие либо leave_group или join_group. А кнопка open_group будет открывать страницу группы, которую мы скоро создадим.

 

Обработка сообщений на сервере

Добавьте следующий код в файл consumers.py:

import json
from channels.generic.websocket import WebsocketConsumer
from accounts.models import User
from .models import Event, Message, Group

class JoinAndLeave(WebsocketConsumer):

    def connect(self):
        self.user = self.scope["user"]
        self.accept()

    def receive(self, text_data=None, bytes_data=None):
        text_data = json.loads(text_data)
        type = text_data.get("type", None)
        if type:
            data = text_data.get("data", None)

        if type == "leave_group":
            self.leave_group(data)
        elif type == "join_group":
            self.join_group(data)

    def leave_group(self, group_uuid):
        group = Group.objects.get(uuid=group_uuid)
        group.remove_user_from_group(self.user)
        data = {
            "type": "leave_group",
            "data": group_uuid
        }
        self.send(json.dumps(data))

    def join_group(self, group_uuid):
        group = Group.objects.get(uuid=group_uuid)
        group.add_user_to_group(self.user)
        data = {
            "type": "join_group",
            "data": group_uuid
        }
        self.send(json.dumps(data))


Добавленный AuthMiddlewareStackвами ранее будет заполнен scope текущим пользователем, которого вы затем сможете получить в функциях.

Эта строка в методе connect потребителя JoinAndLeave извлекает текущего пользователя:

self.user = self.scope["user"]
  • В методе receive код загружает данные JSON, которые отправляет внешний интерфейс, и извлекает значение type и сообщения data.
  • Метод join_group добавляет текущего пользователя в группу, uuid которой был отправлен из внешнего интерфейса, и отправляет те же данные обратно во внешний интерфейс.
  • Метод leave_group удаляет пользователя из группы и отправляет данные обратно во внешний интерфейс.

Данные будут получены в методе onmessage обработчика событий внешнего интерфейса.


Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

В этой строке: window.location.replace(`http://${base_url}groups/${group_uuid}`) забыли /после ${base_url}?

@Селянинов_Игорь, Спасибо, поправил.