Как получать данные с клиентской стороны websocket в Django с помощью каналов
Я пытаюсь получить сообщение websocket на стороне сервера. Оно не принимается. Я неправильно использую функцию? Как должна быть реализована эта функция, чтобы получать сообщения и параллельно выполнять 30-секундные обновления в реальном времени.
Я создал веб-сервер, используя Django Channels (Daphne) на языке Python.
Он отправляет данные async клиенту через websocket, чтобы обновлять графики, созданные с помощью chart.js, каждые 30 секунд. Все это работает нормально.
Однако, когда пользователь делает выбор и график меняется, мне нужно, чтобы новые данные были отправлены немедленно. Поэтому я пытаюсь сделать запрос: клиент отправляет запрос на сервер через websocket, сервер получает запрос и отправляет данные обратно клиенту.
Моя проблема в том, что websocket не получает никаких данных от клиента, хотя все вроде бы в порядке. Я неправильно понимаю, как должны использоваться эти функции? Любая помощь будет оценена по достоинству!
В журнале или консоли нет никаких ошибок, ни на стороне сервера, ни на стороне клиента.
Посмотрите код для моего AsyncWebsocketConsumer:
from asyncio import sleep
from channels.generic.websocket import AsyncWebsocketConsumer
from func.web_read import DatasetBuilder
from datetime import datetime, timedelta, timezone
class ChartDraw(AsyncWebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._dataset: str
self._hash_dataset: hash
self._allmeasurements: DatasetBuilder
async def connect(self):
await self.accept()
self._allmeasurements = DatasetBuilder(1) # some magic, building a dataset
self._date_end: datetime = datetime.now(timezone(timedelta(hours=+1)))
self._date_start: datetime = self._date_end - timedelta(minutes=15)
self._dataset = self._allmeasurements.get_relevant_messages(self._date_start, self._date_end) # gets all the data from a db in the given timeframe.
self._hash_dataset = hash(str(self._dataset))
await self.send(str(self._dataset))
await self.updateDataIfChanged()
async def updateDataIfChanged(self):
while True:
self.updateDate()
self._dataset = self._allmeasurements.get_relevant_messages(self._date_start, self._date_end)
if self._hash_dataset != hash(str(self._dataset)):
await self.send(str(self._dataset))
self._hash_dataset = hash(str(self._dataset))
await sleep(30)
print("30s passed.")
async def receive(self, text_data):
print("New Message!")
print(text_data)
А в javascript вот соответствующие части:
const socket = new WebSocket('ws://localhost:8000/ws/draw_chart/');
console.log("sending to websocket ...");
try {
socket.send("DO YOU HEAR ME!?");
} catch (error) {
console.error("Received error sending data to websocket:", error)
}
Похоже, что полезной документации по этому вопросу очень мало. Я пытался использовать async.gather для параллельного выполнения receive и моей функции «updateDataIfChanged», но безрезультатно.
После того как я понял, что receive все равно работает параллельно и слушает сообщения, я вернул его обратно. Разве он не должен выводить полученный текст сразу после его получения?