Django websockets и каналы group_send не работают
Я начал изучать websockets и хотел бы реализовать realtime коммуникацию между web-клиентом (Angular 13) и приложением на Python. В качестве бэкенда я использовал Django с реализованными websockets и каналами
Поскольку у меня возникла проблема, я упростил код настолько, насколько смог, поэтому многие значения жестко закодированы, чтобы заставить его работать. (Сейчас это один WebClient и один Bot)
Я реализовал 2 потребителя. Бот и веб-клиент:
class BotConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
await self.accept()
await self.channel_layer.group_add("bot","dev")
async def disconnect(self, close_code):
await self.channel_layer.group_discard("bot","dev")
async def receive(self, text_data):
await self.channel_layer.group_send("dev",{"type": "recv","text": "test"})
print("Data sent to group")
class WebClientConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
await self.accept()
await self.channel_layer.group_add("client","dev")
async def recv(self,event):
print("Consumer received smthing from channels")
async def disconnect(self, close_code):
await self.channel_layer.group_discard("client","dev")
async def receive(self, text_data):
print("Smthing received")
моя настройка channel_layer в Setting.py
CHANNEL_LAYERS = {
'default': {
# 'BACKEND': 'channels_redis.core.RedisChannelLayer',
# 'CONFIG': {
# "hosts": [('192.168.1.10', 6379)],
# },
"BACKEND": "channels.layers.InMemoryChannelLayer"
}}
Я пробовал и Redis с запущенным локальным сервером, и каналы в памяти
My websocket's routing.py:
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'live/bot', consumers.BotConsumer.as_asgi()),
re_path(r'live/webclient', consumers.WebClientConsumer.as_asgi()),
]
Мое поведение:
Django logs:
HTTP POST /core/UpdateAvailableServers 200 [0.07, 127.0.0.1:50494]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50497]
**WebSocket HANDSHAKING /live/bot [127.0.0.1:50498]**
**WebSocket CONNECT /live/bot [127.0.0.1:50498]**
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50501]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50504]
HTTP POST /core/GetBots 200 [0.00, 127.0.0.1:50524]
**WebSocket HANDSHAKING /live/webclient [127.0.0.1:50527]**
**WebSocket CONNECT /live/webclient [127.0.0.1:50527]**
HTTP POST /core/GetStatus 200 [0.01, 127.0.0.1:50528]
HTTP POST /core/UpdateAvailableServers 200 [0.02, 127.0.0.1:50531]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50534]
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50537]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50540]
HTTP POST /core/UpdateAvailableServers 200 [0.06, 127.0.0.1:50544]
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50547]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50550]
**Data sent to group**
HTTP POST /core/GetPostInfo 200 [0.00, 127.0.0.1:50554]
HTTP POST /core/GetStatus 200 [0.00, 127.0.0.1:50557]
HTTP POST /core/UpdateAvailableServers 200 [0.06, 127.0.0.1:50560]
HTTP POST /core/GetPostInfo 200 [0.02, 127.0.0.1:50563]
Как вы можете видеть в журнале, я получил успешное websocket соединение от моего python приложения (BOT), а также angular приложения (WebClient) Оба добавлены в группу в connect Function.
Затем приложение бот отправит некоторые данные с помощью websockets и они должны быть отправлены всей группе, что я получу подтверждение, как показано в журнале.
Проблема в том, что мой webclient полностью игнорирует это. Метод recv никогда не выполняется и потребитель WebClient не показывает никакой активности для этого действия.
Есть ли какая-то очевидная ошибка, которую я делаю? (При необходимости я могу предоставить любую дополнительную информацию)
Вы не должны создавать пользовательский канал. Вместо этого назначьте каналу пользовательскую группу.
await self.channel_layer.group_add("bot",self.channel_name)
Также отправьте сообщение сокета группе клиентов в том же канале.
await self.channel_layer.group_send("client",{
"type":"recv",
"message":text_data
})
Смотрите исправленную реализацию ниже.
class BotConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
await self.accept()
await self.channel_layer.group_add("bot",self.channel_name)
async def disconnect(self, close_code):
await self.channel_layer.group_discard("bot",self.channel_name)
async def receive(self, text_data):
await self.channel_layer.group_send("client",{
"type":"recv",
"message":text_data
})
print("Data sent to group")
class WebClientConsumer(AsyncJsonWebsocketConsumer):
async def connect(self):
await self.accept()
await self.channel_layer.group_add("client",self.channel_name)
async def recv(self,event):
print("Consumer received smthing from channels")
async def disconnect(self, close_code):
await self.channel_layer.group_discard("client",self.channel_name)
async def receive(self, text_data):
print("Smthing received")