Как настроить WebSockets для приложения чата в реальном времени с помощью Django Channels и React?

Я работаю над приложением для чата в реальном времени с Django Channels на бэкенде и React на фронтенде. Моя цель - дать пользователям возможность обмениваться сообщениями в реальном времени, но у меня возникают проблемы с правильным подключением всего. Вот краткий обзор того, что я сделал на данный момент:

Бэкенд (Django)

Я настроил Django Channels с поддержкой WebSocket. Вот как выглядит мой файл asgi.py:

import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator
from channels.auth import AuthMiddlewareStack
import chat.routing

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')

django_asgi_app = get_asgi_application()

application = ProtocolTypeRouter({
    "http": django_asgi_app,
    "websocket": AllowedHostsOriginValidator(
        AuthMiddlewareStack(
            URLRouter(
                chat.routing.websocket_urlpatterns
            )
        )
    ),
})

Вот моя настройка маршрутизации WebSocket в файле routing.py:

from django.urls import path
from . import consumers

websocket_urlpatterns = [
    path('ws/chat/<str:chatgroup_name>', consumers.ChatConsumer.as_asgi(),),
]

Потребитель (ChatConsumer) обрабатывает WebSocket-соединения и трансляцию сообщений. Вот его упрощенная версия:

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.chatgroup_name = self.scope['url_route']['kwargs']['chatgroup_name']
        self.user = self.scope['user']
        await self.channel_layer.group_add(self.chatgroup_name, self.channel_name)
        await self.accept()

    async def disconnect(self, close_code):
        await self.channel_layer.group_discard(self.chatgroup_name, self.channel_name)

    async def receive(self, text_data):
        message = json.loads(text_data)['body']
        await self.channel_layer.group_send(
            self.chatgroup_name,
            {
                'type': 'chat_message',
                'message': message,
            }
        )

    async def chat_message(self, event):
        await self.send(text_data=json.dumps(event))

а это страница сообщений в приложении react:

import { useState, useEffect, useRef } from 'react';
// ...additional imports...

export default function MessagesView() {
    const [messages, setMessages] = useState<Message[]>([]);
    const [newMessage, setNewMessage] = useState('');
    const chatContainerRef = useRef<HTMLDivElement>(null);

    const scrollToBottom = () => {
        if (chatContainerRef.current) {
            chatContainerRef.current.scrollTop = chatContainerRef.current.scrollHeight;
        }
    };

    // Fetch messages (placeholder function)
    useEffect(() => {
        const fetchMessages = async () => {
            // Implement API call here
        };
        fetchMessages();
    }, []);

    const handleSendMessage = async () => {
        if (newMessage.trim()) {
            // Implement WebSocket send logic here
            setNewMessage('');
        }
    };

    return (
        <div>
            {/* Chat UI */}
        </div>
    );
}

Как подключить бэкенд Django Channels к фронтенду React через WebSocket? Я не знаю, как инициализировать WebSocket-соединение в React и управлять входящими/исходящими сообщениями.

Вернуться на верх