Ответ
Для реализации WebSocket в Django используется библиотека Django Channels, которая расширяет фреймворк для работы с асинхронными протоколами поверх стандарта ASGI (Asynchronous Server Gateway Interface).
Это позволяет обрабатывать долгоживущие соединения, такие как WebSocket, в то время как стандартные HTTP-запросы по-прежнему обрабатываются синхронным кодом Django.
Основные компоненты:
- ASGI-сервер: Вместо WSGI (Gunicorn) используется ASGI-сервер, например, Daphne или Uvicorn.
- Consumers: Аналоги
viewsдля WebSocket. Это классы, которые обрабатывают события жизненного цикла соединения (connect,disconnect,receive). - Channel Layers: Механизм для коммуникации между различными экземплярами приложения. Обычно реализуется через брокер сообщений, например, Redis.
Пример простого консьюмера чата:
# chat/consumers.py
import json
from channels.generic.websocket import AsyncWebsocketConsumer
class ChatConsumer(AsyncWebsocketConsumer):
# Вызывается при установке соединения
async def connect(self):
self.room_group_name = 'chat_public'
# Присоединение к группе комнаты
await self.channel_layer.group_add(
self.room_group_name,
self.channel_name
)
await self.accept()
# Вызывается при разрыве соединения
async def disconnect(self, close_code):
await self.channel_layer.group_discard(
self.room_group_name,
self.channel_name
)
# Вызывается при получении сообщения от WebSocket
async def receive(self, text_data):
# Отправка сообщения в группу комнаты
await self.channel_layer.group_send(
self.room_group_name,
{
'type': 'chat_message', # Вызывает метод chat_message
'message': text_data
}
)
# Получение сообщения из группы комнаты и отправка его клиенту
async def chat_message(self, event):
message = event['message']
await self.send(text_data=json.dumps({
'message': message
}))
Для работы этого примера необходима настройка роутинга в asgi.py и установка channel_layers в settings.py.