Я проверил, что мой сервер Redis работает и связь с сервером Django.
Каналы и пользователи правильно сохраняются в Redis.
Функция self.channel_layer.send() выполняется без ошибок, но метод send_online_users никогда не запускается (печать операторы внутри send_online_users не отображаются в журналах).
Вот мой код Consumers.py:
Код: Выделить всё
from channels.generic.websocket import AsyncWebsocketConsumer
import redis
from django.conf import settings
import redis.client
from asgiref.sync import sync_to_async
import json
from channels.layers import get_channel_layer
redis_client = redis.StrictRedis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=0)
class UserActivityConsumer(AsyncWebsocketConsumer):
async def connect(self):
self.user = self.scope['user']
if self.user.is_anonymous or not self.user.is_authenticated:
await self.close()
else:
self.channel_name = f'user_activity_{self.user.username}'
await sync_to_async(redis_client.sadd)('online_users', self.user.id)
await sync_to_async(redis_client.sadd)("online_channels",self.channel_name)
await self.accept()
await self.send_to_all()
async def disconnect(self,close_code):
user_id = self.scope['user'].id
await sync_to_async(redis_client.srem)("online_users", user_id)
await sync_to_async(redis_client.srem)("online_channels", self.channel_name)
await self.send_to_all()
async def send_to_all(self):
try:
online_users = await sync_to_async(redis_client.smembers)("online_users")
online_users = [int(user_id) for user_id in online_users]
online_channels = await sync_to_async(redis_client.smembers)("online_channels")
channel_layer = get_channel_layer()
for channel_name in online_channels:
channel_name = channel_name.decode()
await self.channel_layer.send(str(channel_name), {
"type": "send_online_users",
"online_users": online_users
})
except Exception as e:
print(e)
async def send_online_users(self, event):
try:
print('TRIGGERED - send_message')
online_users = event.get('online_users', [])
print(f"Online users: {online_users}")
await self.send(text_data=json.dumps({
"type": "online_users",
"online_users": online_users
}))
print('Message sent to WebSocket client')
except Exception as e:
print(f"Error in send_message: {e}")
Код: Выделить всё
useEffect(() => {
getOnlineUsers();
return () => {
if (socket) {
socketRef.current.close();
}
};
}, []);
const getOnlineUsers = async () => {
if (!socketRef.current || socketRef.current.readyState === WebSocket.CLOSED) {
try {
const token = localStorage.getItem('auth_token');
socketRef.current = new WebSocket(`ws://192.168.1.101:8000/ws/activity/?token=${token}`);
setSocket(socketRef.current);
socketRef.current.onopen = () => {
console.log('WebSocket connection established DM');
};
socketRef.current.onclose = () => {
console.log('WebSocket connection closed DM');
};
socketRef.current.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === "online_users") {
console.log('received');
setOnlineUsers(data.online_users);
}
};
} catch (error) {
console.log(error);
}
}
};
У меня есть система чата в реальном времени, и она работает отлично, и в потребителе чата я назначаю двух пользователей в определенную группу и использую себя. Channel_layer.group_send(group_name,{...}), и он работает отлично, сообщения отправляются без проблем, но когда я пытаюсь отправить данные с именами каналов, это не работает.
Все серверы (интерфейсный интерфейс vite + Сервер Django + Redis) запускается на виртуальной машине Linux с настройками сети VM Box и мостового адаптера.
Конфигурация каналов Django:
Код: Выделить всё
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('192.168.1.101', 6379)],
},
},
}
Когда я вызываю self.channel_layer.send(channel_name, {...}), он должен вызвать send_online_users, который отправляет список онлайн-пользователей клиенту WebSocket.
Что происходит:
Метод send_online_users никогда не запускается. Даже операторы печати не запускаются, и никакие данные не отправляются клиенту.
Подробнее здесь: https://stackoverflow.com/questions/790 ... -trigerred